Java多态中的注意事项

1、“覆盖”私有方法

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

class Derived extends PrivateOverride {
  public void f() { print("public f()"); }
} /* Output:
private f()
*///:~

由于private方法被自动认为是final方法,而且对导出类是屏蔽的。因此,在这种情况下,Derived类中的f()方法就是一个全新的方法;既然基类中的f()方法在子类Derived中不可见,因此甚至也不能被重载。

结论就是:只有非private方法才可以被覆盖。

2、域与静态方法

只有普通的方法调用可以是多态的。

class Super {
  public int field = 0;
  public int getField() { return field; }
}

class Sub extends Super {
  public int field = 1;
  public int getField() { return field; }
  public int getSuperField() { return super.field; }
}

public class FieldAccess {
  public static void main(String[] args) {
    Super sup = new Sub(); // Upcast
    System.out.println("sup.field = " + sup.field +
      ", sup.getField() = " + sup.getField());
    Sub sub = new Sub();
    System.out.println("sub.field = " +
      sub.field + ", sub.getField() = " +
      sub.getField() +
      ", sub.getSuperField() = " +
      sub.getSuperField());
  }
} /* Output:
sup.field = 0, sup.getField() = 1
sub.field = 1, sub.getField() = 1, sub.getSuperField() = 0
*///:~

当Sub对象转型为Super引用时,任何域访问操作都将由编译器解析,因此不是多态的。在本例中,为Super.field和Sub.field分配不同的存储空间。这样,Sub实际上包含两个称为field的域和它从Super处得到的。然而,在引用Sub中的field时所产生的默认域并非Super版本的field域。因此,为了得到Super.field,必须显式地指明super.field。

如果某个方法是静态的,它的行为就不具有多态性。

class StaticSuper {
  public static String staticGet() {
    return "Base staticGet()";
  }
  public String dynamicGet() {
    return "Base dynamicGet()";
  }
}

class StaticSub extends StaticSuper {
  public static String staticGet() {
    return "Derived staticGet()";
  }
  public String dynamicGet() {
    return "Derived dynamicGet()";
  }
}

public class StaticPolymorphism {
  public static void main(String[] args) {
    StaticSuper sup = new StaticSub(); // Upcast
    System.out.println(sup.staticGet());
    System.out.println(sup.dynamicGet());
  }
} /* Output:
Base staticGet()
Derived dynamicGet()
*///:~

静态方法是与类,而并非与单个的对象相关联的。对静态方法的调用不存在任何动态的分配机制。当一个程序调用了一个静态方法,要被调用的方法都是在编译时就被选定的,即调用哪个方法是根据该引用被声明的类型决定的。

时间: 2024-11-12 21:06:37

Java多态中的注意事项的相关文章

java多态中哪些成员具备多态特性

在多态的学习中,当子类继承父类时,子类中的变量哪些具备多态特性,哪些不具备多特特性. 代码: class Father{ public static int x=10; public int y=11; public Father(){ System.out.println("Father"); } public static void info(){ System.out.println("Father's static info method!"); } pub

在java 多态 中 父类作为参数列表的方法

Pet pet=new Dog();  //Pet是父类,Dog是子类. 这个方法是父类做类型,子类实例化. 相关例子: 员工回家的例子: 1,先做一个抽象父类,包含走的想法. package cn.day1; public abstract class Traffic { public abstract void run(); } 2,在创建一个类,包含回家的想法. package cn.day1; public class Employee { public void gohome(Traf

java学习中,面向对象的三大特性:封装、继承、多态 以及 super关键字和方法的重写(java 学习中的小记录)

java学习中,面向对象的三大特性:封装.继承.多态 以及 super关键字和方法的重写(java 学习中的小记录) 作者:王可利(Star·星星) 封装     权限修饰符:public 公共的,private 私有的     封装的步骤:          1.使用private 修饰需要封装的成员变量.          2.提供一个公开的方法设置或者访问私有的属性              设置 通过set方法,命名格式:     set属性名();  属性的首字母要大写 访问 通过ge

Java多态机制和继承中重写重载

关于Java中多态机制 http://www.cnblogs.com/chenssy/p/3372798.html 这篇博文讲的很透彻 大体意思是 多态定义: 多态就是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量倒底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定.因为在程序运行时才确定具体的类,这样,不用修改源程序代码,就可以让引用变量绑定到各种不同的类实现上

Java多态与C++中多态的实现

大牛的文章,值得拜读http://www.ibm.com/developerworks/cn/java/j-lo-polymorph/ 粘贴过来好多图片丢失了 /(ㄒoㄒ)/~~ 众所周知,多态是面向对象编程语言的重要特性,它允许基类的指针或引用指向派生类的对象,而在具体访问时实现方法的动态绑定.C++ 和 Java 作为当前最为流行的两种面向对象编程语言,其内部对于多态的支持到底是如何实现的呢,本文对此做了全面的介绍. 注意到在本文中,指针和引用会互换使用,它们仅是一个抽象概念,表示和另一个对

JAVA之旅(八)——多态的体现,前提,好处,应用,转型,instanceof,多态中成员变量的特点,多态的案例

JAVA之旅(八)--多态的体现,前提,好处,应用,转型,instanceof,多态中成员变量的特点,多态的案例 学习是不能停止的 一.多态 我们今天又要学习一个新的概念了,就是多态,它是面向对象的第三个特征,何谓多态? 定义 某一类事物的多种存在方式 比如 动物中的猫狗,人类中的男人,女人 我们可以把多态理解为事物存在的多种体现形态 当我们new一个猫类的时候,和new 一个动物,其实是一样的,多种形态变现 所以我们可以分这几部分分析 多态的体现 多态的前提 3.多态的好处 4.多态的应用 我

Java语言中的----多态和异常处理

day13 Java语言中的----多态和异常处理 一.概述: 学习Java语言就要理解Java中的面向对象的四大特征:分别是封装.抽象.继承.多态.前面三个我们已经学完了,下面我们来学一下多态.什么是多态?不明思议就是具有两种形态性,一个方法可以定义两种形态,这就是方法的多态性.同时我们还会学习到什么是方法重载.和方法签名. 异常处理就是在编译的时候需要我们手动的去处理一下编译都不能够通过的程序.使用try {} catch{}结构就可以处理异常. 二.多态: 1.所有类的基类是object,

c#中的里氏转换和Java中强制类型转换在多态中的应用

在c#中: 注意: 子类并没有继承父类的构造函数,而是会默认调用父类那个无参数的构造函数. 如果一个子类继承了一个父类,那么这个子类除了可以使用自己的成员外,还可以使用从父类那里继承过来的成员.但是父类永远都只能使用自己的成员,而不能使用子类的成员. 子类之间也不能互相使用对方的成员. 里氏转换的概念: 1).子类可以赋值给父类 2).如果父类中装的是子类对象,那么可以讲这个父类强转为子类对象. namespace 里氏转换_接口练习 { class Program { static void

JAVA多态学习4

好啦,说好的这一节要开讲接口了,嘿嘿,还是老样子,读者最好借助之前说的抽象类进行比较喔O(∩_∩)O哈哈~ 什么是接口? 接口就是给出一些没有内容的方法,封装到一起,到某个类要使用的时候,在根据具体情况把这些方法写出来. 接口的建立语法:interface 接口名{方法;} 语法:class 类名 implements 接口{ 方法; 变量; } 小结:接口是更加抽象的抽象的类,抽象类里的方法可以有方法体,接口里的所有方法都没有方法体.接口体现了程序设计的多态和高内聚低偶合的设计思想. 接口–注