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