JAVA-面向对象之多态

面向对象之多态

----云智科技学习笔记

多态

定义:某一类事物的多种存在形态。
    1. 例:动物中猫,狗。
    2. 猫这个对象对应的类型是猫类型

•    猫 x = new 猫();

    1. 同时猫也是动物中的一种,也可以把猫称为动物。

•    动物  y = new 猫();

•    动物是猫和狗具体事物中抽取出来的父类型。

•    父类型引用指向了子类对象。

1.        程序中体现:

父类或者接口的引用指向或者接收自己的子类对象。

2.        好处和作用:

多态的存在提高了程序的扩展性和后期可维护性

3.        前提:

•    需要存在继承或者实现关系

•    要有覆盖操作

4.        弊端:只能使用父类的引用去访问父类中的成员。

5.        多态:指不同对象收到相同消息时,会产生不同行为。同一个类在不同场合下表现出不同的行为特征。

6.        看如下代码:

abstractclass Animal

{

public abstract void eat();

}

 

class Catextends Animal

{

public void eat()

{

           System.out.println("吃鱼");

}

public void catchMouse()

{

           System.out.println("抓老鼠");

}

}

 

class Dogextends Animal

{

public void eat()

{

           System.out.println("吃骨头");

}

public void kanMen()

{

           System.out.println("看门");

}

}

 

class Pigextends Animal

{

public void eat()

{

           System.out.println("吃饲料");

}

public void gongDi()

{

           System.out.println("拱地");

}

}

 

publicclass Demo

{

public static void main(String agrs[])

{

           /*

           Cat c1=new Cat();

           c1.eat();

           Cat c2=new Cat();

           c2.eat();

           Cat c3=new Cat();

           */

           //发现向上面这样调用太麻烦

           //写了下面的方法来调用

          

           function(new Cat());

 

           function(new Dog());

 

           function(new Pig());

 

           //通过方法的重载实现了如下功能

           //但是发现,动物类会有很多子类,如果每个子类都写个对应的方法,太麻烦了

           //引入多态的概念,对代码进行优化

}

public static void function(Cat c)

{

           c.eat();

}

//因为狗也有类似需求

public static void function(Dog d)

{

           d.eat();

}

 

//因为猪也有类似需求

public static void function(Pig p)

{

           p.eat();

}

}

7.        优化后的代码:

abstractclass Animal

{

public abstract void eat();

}

 

class Catextends Animal

{

public void eat()

{

           System.out.println("吃鱼");

}

public void catchMouse()

{

           System.out.println("抓老鼠");

}

}

 

class Dogextends Animal

{

public void eat()

{

           System.out.println("吃骨头");

}

public void kanMen()

{

           System.out.println("看门");

}

}

 

class Pigextends Animal

{

public void eat()

{

           System.out.println("吃饲料");

}

public void gongDi()

{

           System.out.println("拱地");

}

}

 

publicclass Demo2

{

public static void main(String agrs[])

{

           /*

           Cat c1=new Cat();

           c1.eat();

           Cat c2=new Cat();

           c2.eat();

           Cat c3=new Cat();

           */

         //发现向上面这样调用太麻烦

           //写了下面的方法来调用

          

           Animal c=new Cat();

           function(c);

 

           Animal d=new Dog();

           function(d);

 

           Animal p=new Pig();

           function(p);

 

           //引入多态的概念,对代码进行优化

}

public static void function(Animal a)

{

           a.eat();

                  //但是在这个方法中,只能是调用父类的方法,如果想调用子类的方法,请看Demo3.java

}

}

8.        再次优化后的代码:

abstractclass Animal

{

public abstract void eat();

}

 

class Catextends Animal

{

public void eat()

{

           System.out.println("吃鱼");

}

public void catchMouse()

{

           System.out.println("抓老鼠");

}

}

 

class Dogextends Animal

{

public void eat()

{

           System.out.println("吃骨头");

}

public void kanMen()

{

           System.out.println("看门");

}

}

 

class Pigextends Animal

{

public void eat()

{

           System.out.println("吃饲料");

}

public void gongDi()

{

           System.out.println("拱地");

}

}

 

publicclass Demo3

{

public static void main(String agrs[])

{

           /*

           Cat c1=new Cat();

           c1.eat();

           Cat c2=new Cat();

           c2.eat();

           Cat c3=new Cat();

           */

           //发现向上面这样调用太麻烦

           //写了下面的方法来调用

          

           Animal c=new Cat();

           function(c);

 

           Animal d=new Dog();

           function(d);

 

           Animal p=new Pig();

           function(p);

 

           //引入多态的概念,对代码进行优化

}

public static void function(Animal a)

{

           a.eat();

           //但是在这个方法中,只能是调用父类的方法,如果想调用子类的方法,可以这么做

           if(a instanceof Cat)

           {

                    Cat c=(Cat)a;

                    c.catchMouse();

           }else if(a instanceof Dog)

           {

                    Dog d=(Dog)a;

                    d.kanMen();

           }else if(a instanceof Pig)

           {

                    Pig p=(Pig)a;

                    p.gongDi();

           }

}

}

类型转换:向上转型、向下转型

Animal a=new Cat( );//类型提升,将父类的引用指向了子类

Cat c=(Cat) a ;//强制类型转换,将原来的父类的引用从新转换成该子类对象的引用

但是下面的操作是不允许的:

Animal a=new Animal( );

Cat c=(Cat) a;//这种转换是不允许的。

所以,我们看到,我们能转换的是父类的引用指向了自己的子类对象时,该引用可以被提升,也可以被转换。多态自始至终都是子类对象在做着变化。

多态的特点
    1. 成员函数:

•    口诀:编译看左边,运行看右边。

•    编译时:要查看引用变量所属的类中是否有所调用的成员。

•    在运行时:要查看对象所属的类中是否有所调用的成员。

•    总结:其实在加载进内存时,是加载的是子类的字节码文件,但是只是用来父类型的引用指向,若用父类型的引用去调用时,只能访问父类型中的成员,但是还存在着把该字节码文件强制类型转换成子类的可能,强转后,便有了新的子类引用指向该字节码文件,就可以调用子类和父类中的所有的成员了。

    1. 成员变量:

•    只看引用变量所属的类。即只参考左边,引用类型的类型。

    1. 静态成员:

•    无论在编译还是运行,都参考引用类型。

多态的应用

//学生学习案例

abstract class Student

{

         publicabstract void  study();

         publicvoid sleep()

         {

                   System.out.println("躺着睡觉");

         }

}

 

class DoStudent

{

         publicvoid doSome(Student s)

         {

                   s.study();

                   s.sleep();

         }

}

 

class BaseStu extends Student

{

         publicvoid study()

         {

                   System.out.println("basestudy");

         }

 

         publicvoid sleep()

         {

                   System.out.println("坐着睡觉");

         }

}

 

class AdvStu extends Student

{

         publicvoid study()

         {

                   System.out.println("AdvStustudy");

         }

}

public class Demo

{

         publicstatic void main(String args[])

         {

                   DoStudentds=new DoStudent();

                   ds.doSome(newBaseStu());

                   ds.doSome(newAdvStu());

         }

        

}

//电脑主板案例

class MainBoard

{

         publicvoid run()

         {

                   System.out.println("mainbord run");

         }

         publicvoid usePCI(PCI p)

         {

                   if(p!=null)

                   {

                            p.open();

                            p.close();

                   }

         }

}

 

interface PCI

{

         publicvoid open();

         publicvoid close();

}

 

class NetCard implements PCI

{

         publicvoid open()

         {

                   System.out.println("netcartopen");

         }

 

         publicvoid close()

         {

                   System.out.println("netcartclose");

         }

}

 

class SoundCard implements PCI

{

         publicvoid open()

         {

                   System.out.println("SoundCardopen");

         }

 

         publicvoid close()

         {

                   System.out.println("SoundCardclose");

         }

}

 

public class Demo

{

         publicstatic void main(String args[])

         {

                   MainBoardm=new MainBoard();

                   m.run();

                   m.usePCI(null);

                   m.usePCI(newNetCard());

                   m.usePCI(newSoundCard());

         }

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值