疯狂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、如果执行的是子类中的方法(独一无二,父类中没有),则执行报错;