疯狂JAVA讲义学习——基础代码练习——多态——父类引用指向子类对象:Parent p = new Child()——当使用多态方式调用子类里的方法时,首先检查父类中是否有该方法,如果没有,则编译错误
多态的实现方式
方式一:重写:
这个内容已经在上一章节详细讲过,就不再阐述,详细可访问:Java 重写(Override)与重载(Overload)。
方式二:接口
-
1. 生活中的接口最具代表性的就是插座,例如一个三接头的插头都能接在三孔插座中,因为这个是每个国家都有各自规定的接口规则,有可能到国外就不行,那是因为国外自己定义的接口类型。
-
2. java中的接口类似于生活中的接口,就是一些方法特征的集合,但没有方法的实现。
方式三:抽象类和抽象方法
=========================================================
简单理解:重写、重载是多态的表现形式(实现形式)。
多态存在的三个必要条件
- 继承
- 重写
- 父类引用指向子类对象:Parent p = new Child(); ---------- 参考继承中的示例
当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,再去调用子类的同名方法。
多态的好处:可以使程序有良好的扩展,并可以对所有类的对象进行通用处理。
=========================================================
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
class BaseClass
{
public int book = 6 ;
public void base()
{
System.out.println( "fu---pu" );
}
public void test()
{
System.out.println( "fu--------fugai" );
}
}
public class SubClass extends BaseClass
{
public String book = "轻量级Java EE企业应用实战" ;
public void test()
{
System.out.println( "zi--------fugai" );
}
public void sub()
{
System.out.println( "zi------------pu" );
}
public static void main(String[] args)
{
BaseClass bc = new BaseClass();
System.out.println(bc.book);
bc.base();
bc.test();
System.out.println( "------------------------------------------0" );
SubClass sc = new SubClass();
System.out.println(sc.book);
sc.base();
sc.test();
System.out.println( "------------------------------------------1" );
BaseClass ploymophicBc = new SubClass();
System.out.println(ploymophicBc.book);
ploymophicBc.base();
ploymophicBc.test();
}
}
|
class BaseClass { public int book = 6; public void base() { System.out.println("父类的普通方法"); } public void test() { System.out.println("父类的被覆盖的方法"); } } public class SubClass extends BaseClass { //重新定义一个book实例变量隐藏父类的book实例变量 public String book = "轻量级Java EE企业应用实战"; public void test() { System.out.println("子类的覆盖父类的方法"); } public void sub() { System.out.println("子类的普通方法"); } public static void main(String[] args) { // 下面编译时类型和运行时类型完全一样,因此不存在多态 BaseClass bc = new BaseClass(); // 输出 6 System.out.println(bc.book); // 下面两次调用将执行BaseClass的方法 bc.base(); bc.test(); // 下面编译时类型和运行时类型完全一样,因此不存在多态 SubClass sc = new SubClass(); // 输出"轻量级Java EE企业应用实战" System.out.println(sc.book); // 下面调用将执行从父类继承到的base()方法 sc.base(); // 下面调用将执行从当前类的test()方法 sc.test(); // 下面编译时类型和运行时类型不一样,多态发生 BaseClass ploymophicBc = new SubClass(); // 输出6 —— 表明访问的是父类对象的实例变量 System.out.println(ploymophicBc.book); // 下面调用将执行从父类继承到的base()方法 ploymophicBc.base(); // 下面调用将执行从当前类的test()方法 ploymophicBc.test(); // 因为ploymophicBc的编译类型是BaseClass, // BaseClass类没有提供sub方法,所以下面代码编译时会出现错误。 // ploymophicBc.sub(); // 编译器推断v1是SubClass类型 var v1 = new SubClass(); // 由于ploymophicBc的编译时类型是BaseClass // 因此编译器推断v2是BaseClass类型 var v2 = ploymophicBc; // 由于BaseClass类没有提供sub方法,所以下面代码编译时会出现错误。 v2.sub(); } }
======================================================
class Animal { public void move() { System.out.println("动物可以移动"); } } class Dog extends Animal { public void move() { System.out.println("狗可以跑和走"); } public void bark() { System.out.println("狗可以叫"); super.move(); } } public class TestDog { public static void main(String args[]) { Animal b = new Dog(); b.move(); // b.bark(); } }
多态时:
1、父类中和子类中有相同变量,则显示父类变量;
2、父类中和子类中有相同方法,则执行子类方法;
3、如果执行的是父类中的方法(独一无二,子类中没有),则执行父类中的方法;
4、如果执行的是子类中的方法(独一无二,父类中没有),则执行报错;