java复习:多态


多态

1. 多态的定义:
某种事物的多种体现形式。例如人类中的男人、女人。
男人这个对象对应的类型是男人类型,如:男人 x = new男人();, 同时男人也是人类中的一种,也可以把男人称为人类。人类 y = new男人(); 也可以,父类的引用可以接受自己的子类对象。
2. 多态的前提
类与类之间有关系,还有一个前提就是,存在覆盖,覆盖父类的 功能。
3. 多态的好处

    提高了程序的扩展性,但是只有引用访问父类中的成员。

4. 多态的简单应用实例

(1)动物都有基本的 吃饭功能,并且两个对象都有自己的特有功能。建立两个对象猫、狗,它们都有基本的吃饭功能,同时,它们可以有抓老鼠和看门的特有功能。

 abstract class Animal
{
    abstract void eat();
}
class Cat extends Animal
{
    public void eat()
    {
        System.out.println("eat fish");
    }
    public static void CatchMouse()
    {
        System.out.println("Catch Mouse");
    }
}
class Dog extends Animal
{
    public void eat()
    {
        System.out.println("eat bone");
    }
    public void KanMen()
    {
        System.out.println("KanMen");
    }
}
class Demo
{
    public static void main(String[] args) 
    {
        Cat c =new Cat();
        c.eat();
        c.CatchMouse();
        Dog d=new Dog();
        d.eat();
        d.KanMen();
    }
}

(2)但是发现上面的程序有一个问题,如果动物太多,程序就不易扩展,所以想到将共同的功能抽取出来单独的进行封装,并使用多态对程序提高程序的扩展性。

但是要注意额是,只能使用父类中的引用访问父类中的成员。也就是说使用了多态,父类型的引用在使用功能时,不能直接调用子类中的特有方法。如:Animal a = new Cat(); (Cat类型提升了,向上转型)。这代码就是多态的体现,假设子类Cat中有特有的抓老鼠功能,父类型的 a就不能直接调用。

如果此时父类的引用想要调用Cat中特有的方法,就需要强制将父类的引用,转成子类类型,向下转型。如:Catc = (Cat)a;但是有一点要注意的是:如果父类可以创建对象,如:Animal a = new Animal(); 此时,就不能向下转型了,Cat c = (Cat)a; 这样的代码就变得不容许,编译时会报错。所以千万不能出现这样的操作,就是将父类对象转成子类类型。

下面就是一个多态的示例:

abstract class Animal//定义父类的功能
{
    abstract void eat();
}
class Cat extends Animal//子类Cat继承父类Animal    
{
    public void eat()//覆盖父类功能
    {
        System.out.println("eat fish");
    }
    public void CatMouse()//子类特有的功能
    {
        System.out.println(" catch mouse ");
    }
}
class Dog extends Animal//子类Dog类
{
    public void eat()//覆盖父类功能
    {
        System.out.println("eat bone");
    }
    public void Kanmen()//子类特有的功能
    {
        System.out.println("kan men");
    }
}
class Demo
{
    public static void main(String[] args)
    {
        Cat c=new Cat();
        function(c);
        function(new Dog());
    }
    public static void function(Animal a)
    //(Animal a)相当于Animal a=new Cat(); Animal a=new Dog();//向上转型
    {
        if(a instanceof Cat)//instanceof判断所属类型
        {
            a.eat();
            Cat c=(Cat)a;//向下转型
            c.CatMouse();
        }
        else if (a instanceof Dog)
        {
            a.eat();
            Dog d=new Dog();//向下转型
            d.Kanmen();
        }

    }   
}

5.多态的成员变量特点
(1)非静态的成员函数
编译时的注意事项:参阅引用型变量所属的类(父类)中是否引用的方法,有则通过编译没有 则不能 通过。(简单点的描述:多态时编译看左边,运行看右边)。
举例说明:

class Fu
{
    void method1()
    {
        System.out.println("Fu method1");
    }
    void method2()
    {
        System.out.println("Fu method2");
    }
}
class Zi extends Fu
{
    void method1()
    {
        System.out.println("Zi method1");
    }
    void method3()
    {
        System.out.println("Zi method2");
    }
}
class Demo
{
    public static void main(String[] args)
    {
        Fu f=new Zi();
        f.method1();//覆盖父类的方法
        f.method2();//使用父类中的函数方法
        //f.method3();如果有此句的情况下,不能通过编译;参阅引用型变量所属的类(父类)中是否有引用的方法(编译看左边,运行看右边)
    }
}

这里写图片描述
(2)对于成员变量的特点
无论编译和运行,都参考左边(引用变量所属的类)。如:多态中的父类引用调用成员变量时,如果父类和子类有同名的成员变量,那么被调用的是父类中的成员变量。

class Fu
{
    int num=1;
}
class Zi extends Fu
{
    int num=2;
}
class Demo
{
    public static void main(String[] args)
    {
        Fu f=new Fu();
        System.out.println(f.num);
        Zi z=new Zi();
        System.out.println(z.num);
    }
}

结果为:
这里写图片描述

(3)对于静态的成员函数(和成员变量一样打印的是左边)

class Fu
{
    static void method1()
    {
        System.out.println("Fu method1");
    }
}
class Zi extends Fu
{
    static void method1()
    {
        System.out.println("Zi method1");
    }
}
class Demo
{
    public static void main(String[] args)
    {
        Fu f=new Zi();
        f.method1();//静态成员变量查看左边
    }
}

这里写图片描述
6.多态的主板实例
让主板通过PCI来使主板和网卡、声卡的相互连接

//定义接口
interface PCI
{
    public void open();
    public void close();
}
class MainBoard
{
    public void run()
    {
        System.out.println("MainBoard Run");
    }
/*多态的应用,提高了程序的扩展,相当于 PCI p=new SoundCard();
PCI p=new NetCard();*/
    public void UsePCI(PCI p)性
    {
        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 Demo
{
    public static void main(String[] args)
    {
        MainBoard mb=new MainBoard();
        mb.run();
        mb.UsePCI(new NetCard());
        mb.UsePCI(new SoundCard());
    }
}

这里写图片描述
7.object类
(1)Object类是所有对象的直接或间接父类。本身具有很多类或者是方法

//相当于里面隐含的构造函数为super()即Object()
class Demo extends Object
{
    Demo()
    {
        super();
    }
}
class ObjectDemo
{
    public static void main(String[] args)
    {
        Demo d1=new Demo();
        Demo d2=new Demo();
        Demo d3=d1;
        System.out.println(d1.equals(d2));
        System.out.println(d1.equals(d3));//其实比较的是地址
    }
}

这里写图片描述
(2)想建立自己的Demo类的比较方式来比较Demo的特征,则需要自己来定义功能

class Demo
{
    private int num;
    Demo(int num)
    {
        this.num=num;
    }
    //自己定义函数的功能,定义compare函数
    public boolean compare(Demo d) 
    {
        return this.num==d.num;
    }
}
class ObjectDemo
{
    public static void main(String[] args)
    {
        Demo d1=new Demo(4);
        Demo d2=new Demo(5);
        System.out.println(d1.compare(d2));
    }
}

(3)但是父类已经有了比较功能的功能函数equals,没必要重新定义,只要沿袭父类的功能就可以了

class Demo
{
    Demo(int num)
    {
        this.num=num;
    }
    //复写equals原来的功能,不用重新定义新的函数 
    public boolean equals(Object obj)
    {
        return this.num=obj.num;
    }
}
class ObjectDemo
{
    public static void main(String[] args)
    {
        Demo d1=new Demo(4);
        Demo d2=new Demo(5);
        System.out.println(d1.equals(d2));
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值