java小心机(6)| 多态的一些坑

6次阅读

共计 2495 个字符,预计需要花费 7 分钟才能阅读完成。

对于 ” 多态 ” 的概念, 想必大家都很熟悉了, 但我们还是来回顾一下吧
class Actor {
public void act(){
System.out.println(“Actor”);
}
}

class HappyActor extends Actor{
@Override
public void act() {
System.out.println(“HappyActor”);
}
}

class SadActor extends Actor{
@Override
public void act() {
System.out.println(“SadActor”);
}
}

public class Test {
public static void main(String[] args) {
Actor hActor = new HappyActor();// 向上转型
Actor sActor = new SadActor();// 向上转型
hActor.act();
sActor.act();
}
}
//out:
HappyActor
SadActor
上面例子中,HappyActor 和 SadActor 都继承 Actor 并重写了 act 方法, 在 main 函数中, 两个 Actor 对象调用相同方法产生不同的结果, 就称为 ” 多态 ”。
在设计程序中,” 多态 ” 可使代码变得灵活, 有时候还是很好使得, 但也有一些坑在里面, 下面就给你一一道来
坑 1 “ 覆盖 ” 私有方法
public class PrivateOverride {
private void f(){
System.out.println(“private f()”);
}

public static void main(String[] args){
PrivateOverride po = new Derived();
po.f();
}
}

class Derived extends PrivateOverride{
public void f(){
System.out.println(“public f()”);
}
}
//out:
private f()
我们期望输出的是 public f(), 但结果并非我们所想。PrivateOverride 中的 f() 方法是私有的, 对它的子类是不可见的,Derived 的 f() 方法无法覆盖它。
结论:无法覆盖私有方法。需要注意,子类中方法切勿与父类中的私有方法同名,否则会容易混淆。
坑 2 域与静态方法不存在多态
1. 域
class SuperClass {
public String field = “Super field”;

public String getField() {
return field;
}
}

class SubClass extends SuperClass {
public String field = “Sub field”;

@Override
public String getField() {
return field;
}

public String getSuperField() {
return super.getField();
}
}

public class FieldAccess {
public static void main(String[] args) {
SuperClass sup = new SubClass();// 向上转型
System.out.println(“sup.field = ” + sup.field
+ “, sup.getField() = ” + sup.getField());

SubClass sub = new SubClass();
System.out.println(“sub.field = ” + sub.field
+ “, sub.getField() = ” + sub.getField()
+”, sub.getSuperField() = ” + sub.getSuperField());
}
}
//out:
sup.field = Super field, sup.getField() = Sub field
sub.field = Sub field, sub.getField() = Sub field,
sub.getSuperField() = Super field
域的访问操作是由编译器解析的, 所以不是多态的。(扩展:多态是由动态绑定实现的,即是在程序运行期对数据做绑定)
SuperClass 中的 field 和 SubClass 中的 field 分配了不同的内存空间, 在 SubClass 中实际上包含了两个 field: 一个是自己的和从父类 SuperClass 中继承的。子类 SubClass 中可使用 super.field 显示地指明 SuperClass 中的 field。
2. 静态方法
class StaticSuper{
public static String staticGet(){
return “Base staticGet()”;
}

public String dynamicGet(){
return “Base dynamicGet()”;
}
}

class StaticSub extends StaticSuper{
public static String staticGet(){
return “Base staticGet()”;
}

@Override
public String dynamicGet(){
return “Base dynamicGet()”;
}
}
public class StaticMethod {
public static void main(String[] args) {
StaticSuper sup = new StaticSub();
System.out.println(sup.staticGet());
System.out.println(sup.dynamicGet());
}
}
//out:
Base staticGet()
Base dynamicGet()
静态方法无法被覆盖, 无法实现多态。
总结:域与静态方法都无法实现多态。需要注意,尽可能不对父类和子类的域使用相同的名字,无法覆盖的方法不使用相同名字,以免造成混淆。
推荐阅读:
老同学又来借钱了
「深入浅出」集合 Set
你、我
您的点赞、转发是对我最大的支持!

 THANDKS
End –
一个立志成大腿而每天努力奋斗的年轻人
伴学习伴成长,成长之路你并不孤单!

正文完
 0