JavaSE笔记6.11-面向对象-多态

一. 概念

1. 引入

可以理解为事物存在的多种体现形态。
人:男人、女人
动物:猫、狗

猫 x=new 猫();
动物 x=new 猫();

abstract class Animal
{
     
	abstract void eat();
}

class Cat extends Animal
{
     
	public void eat()
	{
     
		System.out.println("吃鱼");
	}
}

class Dog extends Animal
{
     
	public void eat()
	{
     
		System.out.println("吃骨头");
	}
}

class DuoTaiDemo 
{
     
	public static void main(String[] args) 
	{
     
		function(new Cat());
		function(new Dog());
	}
	public static void function(Animal a)
	{
     
		a.eat();
	}
}
2. 多态的体现

父类的引用指向了自己的子类对象
Animal c=new Cat();

父类的引用可以接收自己的子类对象
function(new Cat());

3. 多态的前提
  • 必须是类与类之间有关系:要么是继承,要么实现。
  • 通常还有一个前提:存在覆盖。
4. 多态的好处

多态的出现大大地提高了程序的扩展性

5. 多态的弊端

提高了扩展性,但是只能使用父类的引用访问父类中的成员

二. 父类引用如何使用子类特有方法

1. 强制将父类引用,转换成子类类型

父类引用指向自己的子类对象时:该引用可以被提升(向上),也可以被强制转换(向下)

abstract class Animal
{
     
	abstract void eat();
}

class Cat extends Animal
{
     
	public void eat()
	{
     
		System.out.println("吃鱼");
	}
	public void catchMouse()
	{
     
		System.out.println("抓老鼠");
	}
}

class Dog extends Animal
{
     
	public void eat()
	{
     
		System.out.println("吃骨头");
	}
	public void KanJia()
	{
     
		System.out.println("看家");
	}
}

class  DuoTaiDemo2
{
     
	public static void main(String[] args) 
	{
     
		function(new Cat());
	}
	public static void function(Animal a)
	{
     
		a.eat();
		//如果想要调用猫的特有方法时,如何操作
		//强制将父类引用,转成子类类型
		Cat c=(Cat)a;
		c.catchMouse();
	}
}
2.判断各子类类型

判断是哪个子类的实例:用关键字instanceof
用法:对象 instanceof 类型(类类型/接口类型)

abstract class Animal
{
     
	abstract void eat();
}

class Cat extends Animal
{
     
	public void eat()
	{
     
		System.out.println("吃鱼");
	}
	public void catchMouse()
	{
     
		System.out.println("抓老鼠");
	}
}

class Dog extends Animal
{
     
	public void eat()
	{
     
		System.out.println("吃骨头");
	}
	public void KanJia()
	{
     
		System.out.println("看家");
	}
}

class Pig extends Animal
{
     
	public void eat()
	{
     
		System.out.println("饲料");
	}
	public void GongDi()
	{
     
		System.out.println("拱地");
	}
}

class  DuoTaiDemo2
{
     
	public static void main(String[] args) 
	{
     
		function(new Dog());
		function(new Cat());
		function(new Pig());
	}
	public static void function(Animal a)
	{
     
		a.eat();
		if(a instanceof Cat)
		{
     
			Cat c=(Cat)a;
			c.catchMouse();
		}
		else if(a instanceof Dog)
		{
     
			Dog c=(Dog)a;
			c.KanJia();
		}
		else if(a instanceof Pig)
		{
     
			Pig c=(Pig)a;
			c.GongDi();
		}
	}
}

三. 多态中成员的特点

1. 成员函数–编译看左边

编译时期:参阅引用型变量所属的类中是否有调用的方法。
如果有,编译通过;如果没有,编译失败。
JavaSE笔记6.11-面向对象-多态_第1张图片

2. 成员函数–运行看右边

运行时期:参阅对象所属的类中是否有调用的方法。

class Fu
{
     
    void method1()
    {
     
        System.out.println("Fu method_1");
    }
    void method2()
    {
     
        System.out.println("Fu method_2");
    }
}

class Zi extends Fu
{
     
    void method1()
    {
     
        System.out.println("Zi method_1");
    }
}
class DuoTaiDemo4
{
     
    public static void main(String[] args)
    {
     
        Fu f=new Zi();
        f.method1();
        f.method2();
    }
}

输出结果是:
Zi method_1
Fu method_2

3. 成员变量–编译&运行都看左边

无论编译或运行,都参考引用型变量所属的类

class Fu
{
     
    static int num = 5;
}
class Zi extends Fu
{
     
    static int num = 8;
}
class DuoTaiDemo4
{
     
    public static void main(String[] args)
    {
     
        Fu f=new Zi();
        System.out.println(f.num);

        Zi z=new Zi();
        System.out.println(z.num);
    }
}

输出结果是:
5
8

4. 静态成员函数–编译&运行都看左边

无论编译或运行,都参考引用型变量所属的类

class Fu
{
     
    static void method4()
    {
     
        System.out.println("fu method_4");
    }
}
class Zi extends Fu
{
     
    static void method4()
    {
     
        System.out.println("zi method_4");
    }
}
class DuoTaiDemo4
{
     
    public static void main(String[] args)
    {
     
        Fu f=new Zi();
        f.method4();

        Zi z=new Zi();
        z.method4();
    }
}

输出结果是:
fu method_4
zi method_4

四. 例子

JavaSE笔记6.11-面向对象-多态_第2张图片

interface PCI
{
     
    public abstract void open();
    public abstract void close();
}

class MainBoard
{
     
    public void run()
    {
     
        System.out.println("MainBoard Run");
    }
    public void usePCI(PCI p)
    {
     
        if(p!=null)
        {
     
            p.open();
            p.close();
        }
    }
}

class NetCard implements PCI
{
     
    public void open()
    {
     
        System.out.println("NetCard open");
    }
    public void close()
    {
     
        System.out.println("NetCard close");
    }
}

class SoundCard implements PCI
{
     
    public void open()
    {
     
        System.out.println("SoundCard open");
    }
    public void close()
    {
     
        System.out.println("SoundCard close");
    }
}

class DuoTaiDemo5
{
     
    public static void main(String[] args)
    {
     
        MainBoard mb=new MainBoard();
        mb.run();
        mb.usePCI(null);

        //PCI p=new NetCard()接口型引用指向自己的子类对象
        mb.usePCI(new NetCard());
        //PCI p=new SoundCard()接口型引用指向自己的子类对象
        mb.usePCI(new SoundCard());
    }
}

输出结果是:
MainBoard Run
NetCard open
NetCard close
SoundCard open
SoundCard close

你可能感兴趣的:(JavaSE,多态,javase,面向对象编程)