![]() |
微笑的手套 · Navigator:share() 方法 ...· 3 月前 · |
![]() |
温柔的红薯 · CAS Authentication :: ...· 3 月前 · |
![]() |
刚分手的马铃薯 · CIImage 类 (CoreImage) ...· 5 月前 · |
![]() |
爱旅游的丝瓜 · JS之innerHTML,innerText ...· 9 月前 · |
![]() |
愤怒的菠菜 · nodejs哪个版本支持 async ...· 1 年前 · |
同一个事件发生在不同的对象上会产生不同的结果。
多态的优点 1. 消除类型之间的耦合关系当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,再去调用子类的同名方法。
多态的好处:可以使程序有良好的扩展,并可以对所有类的对象进行通用处理。
以下是一个多态实例的演示,详细说明请看注释:
执行以上程序,输出结果为:
虚函数的存在是为了多态。
Java 中其实没有虚函数的概念,它的普通函数就相当于 C++ 的虚函数,动态绑定是Java的默认行为。如果 Java 中不希望某个函数具有虚函数特性,可以加上 final 关键字变成非虚函数。
我们将介绍在 Java 中,当设计类时,被重写的方法的行为怎样影响多态性。
我们已经讨论了方法的重写,也就是子类能够重写父类的方法。
当子类对象调用重写的方法时,调用的是子类的方法,而不是父类中被重写的方法。
要想调用父类中被重写的方法,则必须使用关键字 super 。
假设下面的类继承Employee类:
现在我们仔细阅读下面的代码,尝试给出它的输出结果:
以上实例编译运行结果如下:
Employee 构造函数 Employee 构造函数 使用 Salary 的引用调用 mailCheck -- Salary 类的 mailCheck 方法 邮寄支票给:员工 A ,工资为:3600.0 使用 Employee 的引用调用 mailCheck-- Salary 类的 mailCheck 方法 邮寄支票给:员工 B ,工资为:2400.0实例中,实例化了两个 Salary 对象:一个使用 Salary 引用 s,另一个使用 Employee 引用 e。
在编译的时候,编译器使用 Employee 类中的 mailCheck() 方法验证该语句, 但是在运行的时候,Java虚拟机(JVM)调用的是 Salary 类中的 mailCheck() 方法。
Java中所有的方法都能以这种方式表现,因此,重写的方法能在运行时调用,不管编译的时候源代码中引用变量是什么数据类型。
2. java中的接口类似于生活中的接口,就是一些方法特征的集合,但没有方法的实现。具体可以看 java接口 这一章节的内容。
一、使用父类类型的引用指向子类的对象;
二、该引用只能调用父类中定义的方法和变量;
三、如果子类中重写了父类中的一个方法,那么在调用这个方法的时候,将会调用子类中的这个方法;(动态连接、动态调用);
四、变量不能被重写(覆盖),”重写“的概念只针对方法,如果在子类中”重写“了父类中的变量,那么在编译时会报错。
九刃
528***187@qq.com
xiaohau7988
107***2774@qq.com
我是小萌新
239***9370@qq.com
class Animal{ public int age; //此处在Animal中定义类型为int,名为age的变量。 public void move(){ System.out.println("动物总是不安分"); class Dog extends Animal{ public double age; //此处在Dog中定义新类型double,名为age的变量。当然int尝试也可以。 public void move(){ age =10; System.out.println("狗跑的很快"); class Cat extends Animal{ public void move(){ super.age = 3; //此处继承age,并赋值为3.且该类中未重新定义变量。 System.out.println("猫跳的很高"); public class DuiXiang03{ public static void main(String args[]){ Animal a = new Animal(); // Animal 对象 Animal b = new Dog(); // Dog 对象 Animal c =new Cat(); //Cat 对象 Dog d= new Dog(); Cat e= new Cat(); a.move();//执行 Animal 类的方法 b.move();//执行 Dog 类的方法 c.move();//执行 Cat 类的方法 d.move();//执行Dog 类的方法 e.move();//执行 Cat 类的方法 Object aValue = a.age; Object bValue = b.age; // b.age有两个age值,一个是自定义的age值,一个是继承的age值 Object cValue = c.age; Object dValue = d.age; // d.age有两个age值,一个是自定义的age值,一个是继承的age值 Object eValue =e.age; System.out.println("The type of "+a.age+" is "+(aValue instanceof Double ? "double" : (aValue instanceof Integer ? "int" : ""))); // Animal 类中的 age 未被赋值 System.out.println("The type of "+b.age+" is "+(bValue instanceof Double ? "double" : (bValue instanceof Integer ? "int" : ""))); // b.age有两个age值,输出取引用名为Animal的int类型值 System.out.println("The type of "+c.age+" is "+(cValue instanceof Double ? "double" : (cValue instanceof Integer ? "int" : ""))); // c.age只有一个age值,是super所继承的Animal中的age值,再被赋值为3 System.out.println("The type of "+d.age+" is "+(dValue instanceof Double ? "double" : (dValue instanceof Integer ? "int" : ""))); // d.age有两个age值,输出取引用名为Dog的double类型值 System.out.println("The type of "+e.age+" is "+(eValue instanceof Double ? "double" : (eValue instanceof Integer ? "int" : ""))); // c.age只有一个age值,是super所继承的Animal中的age值,再被赋值为3输出的结果为:
动物总是不安分 狗跑的很快 猫跳的很高 狗跑的很快 猫跳的很高 The type of 0 is int The type of 0 is int The type of 3 is int The type of 10.0 is double The type of 3 is int
多态
176***64709@163.com
1. Java 虚函数
虚函数的存在是为了多态。
C++ 中普通成员函数加上 virtual 关键字就成为虚函数。
Java 中其实没有虚函数的概念,它的普通函数就相当于 C++ 的虚函数,动态绑定是 Java 的默认行为。如果 Java 中不希望某个函数具有虚函数特性,可以加上 final 关键字变成非虚函数。
PS: 其实 C++ 和 Java 在虚函数的观点大同小异,异曲同工罢了。
2. Java抽象函数(纯虚函数)
抽象函数或者说是纯虚函数的存在是为了定义接口。
C++ 中纯虚函数形式为:
virtual void print() = 0;
Java 中纯虚函数形式为:
abstract void print();
PS: 在抽象函数方面 C++ 和 Java 还是换汤不换药。
3. Java 抽象类
抽象类的存在是因为父类中既包括子类共性函数的具体定义,也包括需要子类各自实现的函数接口。抽象类中可以有数据成员和非抽象方法。
C++ 中抽象类只需要包括纯虚函数,既是一个抽象类。如果仅仅包括虚函数,不能定义为抽象类,因为类中其实没有抽象的概念。
Java 抽象类是用 abstract 修饰声明的类。
PS: 抽象类其实是一个半虚半实的东西,可以全部为虚,这时候变成接口。
4. Java 接口
接口的存在是为了形成一种规约。接口中不能有普通成员变量,也不能具有非纯虚函数。
C++ 中接口其实就是全虚基类。
Java 中接口是用 interface 修饰的类。
PS: 接口就是虚到极点的抽象类。
5. 小结
C++ 虚函数 == Java 普通函数 C++ 纯虚函数 == Java 抽象函数 C++ 抽象类 == Java 抽象类 C++ 虚基类 == Java 接口
yhxf1985
yhx***fan@163.com
命数如织当为磐石
and***_e@163.com
在向上引用时,子类的同名非静态成员方法与成员变量会覆盖父类的同名非静态成员方法和成员变量,子类的同名静态成员方法会被父类的同名静态成员方法隐藏,也就是说被覆盖。
可以通过 super 关键字在子类中显式调用父类中被覆盖的非静态成员方法和成员变量。
public class Test { public static void main(String[] args) { System.out.println("Polymorghpic Test"); Animal a = new Dog(); Animal b = new Dog("smith", 5); // 子类的非静态方法与变量覆盖父类 a.getInfo(); // 子类通过super调用父类的非静态成员方法和变量 a.getSuperInfo(); // 子类的静态方法被父类隐藏 a.hello(); b.getInfo(); b.hello(); class Animal { String name; int age; public Animal() { name = "alex"; age = 1; public Animal(String nm, int ag) { name = nm; age = ag; public void getInfo() { System.out.print(name + "'s age is " + age + '\n'); public void getSuperInfo() {} public static void hello() { System.out.println("Greeting from Animal"); class Dog extends Animal { String name; int age; public Dog() { name = "prter"; age = 3; public Dog(String nm, int ag) { super(nm, ag); public void getInfo() { System.out.print(name + "'s age is " + age + '\n'); // 通过super显式调用父类的非静态成员方法 public void getSuperInfo() { super.getInfo(); public static void hello() { System.out.println("Greeting from Dog");Polymorghpic Test prter's age is 3 alex's age is 1 Greeting from Animal null's age is 0 Greeting from Animal
bluelich
blu***ch@sina.cn
静态方法被子类重写,要看父类引用还是子类引用指向子类对象,如果是父类引用指向子类对象,那么调静态方法时,会调用父类的静态方法,如果是子类引用指向子类对象,那么调静态方法时,会调用子类的静态方法。
public class Test { public static void main(String[] args) { System.out.println("Polymorghpic Test"); Animal a = new Dog(); Animal b = new Dog("smith", 5); Dog c = new Dog(); // 子类的非静态方法与变量覆盖父类 a.getInfo(); // 子类通过super调用父类的非静态成员方法和变量 a.getSuperInfo(); // 子类的静态方法被父类隐藏 a.hello(); b.getInfo(); b.hello(); // 调用子类的静态方法 c.hello(); class Animal { String name; int age; public Animal() { name = "alex"; age = 1; public Animal(String nm, int ag) { name = nm; age = ag; public void getInfo() { System.out.print(name + "'s age is " + age + '\n'); public void getSuperInfo() {} public static void hello() { System.out.println("Greeting from Animal"); class Dog extends Animal { String name; int age; public Dog() { name = "prter"; age = 3; public Dog(String nm, int ag) { super(nm, ag); public void getInfo() { System.out.print(name + "'s age is " + age + '\n'); // 通过super显式调用父类的非静态成员方法 public void getSuperInfo() { super.getInfo(); public static void hello() { System.out.println("Greeting from Dog");输出结果:
Polymorghpic Test prter's age is 3 alex's age is 1 Greeting from Animal null's age is 0 Greeting from Animal Greeting from Dog
![]() |
愤怒的菠菜 · nodejs哪个版本支持 async await-掘金 1 年前 |