面向对象(多态)

多态

可以理解为事物存在的多种体现形态
动物:猫,狗
猫 x = new 猫();
动物 x = new 猫();
-----------------------------
多态的体现:
父类的引用指向了自己的子类对象
父类 x = new 子类();
父类是向上抽取的结果,动物 x = new 猫(); new出来的猫具有动物的所有抽象特征
如,猫有动物所具有的吃,睡得抽象特征
但是 猫 x = new 动物();就不行,一个动物对象不一定具有猫的特征
--------------------------------
好处:多态的出现大大提高了程序拓展性
---------------------------------
前提:必须是类与类之间有关系,要么继承,要么实现
还有一个前提,就是存在覆盖,即,父类里面有个吃饭,
但是子类必须覆盖父类的吃饭,如,猫吃鱼,狗吃骨头
---------------------------------
弊端:提高了扩展性,但是只能使用父类的引用访问父类中的成员
public class Test {
    public static void main(String[] args) {
        Animal a = new Mao();
        a.eat();
        a.catchMouse();--------------->这句代码是会报错的,因为它是猫特有的
    }
}
 
abstract class Animal{
    abstract void eat();
    }
 
class Mao extends Animal{
    public void eat(){System.out.println("吃鱼");}
    public void catchMouse(){System.out.println("抓老鼠");}
    }
-------------------------------------------------

向上转型

-------------------------------------------------------
多态的实例
abstract class Student
{
    public abstract void study();
    public void sleep()
    {
        System.out.println("躺着睡");
    }
}
————————————————
class DoStudent
{
    public void doSome(Student stu)
    {
        stu.study();
        stu.sleep();
    }
}
————————————————
class BaseStudent extends Student
{
    public void study()
    {
        System.out.println("base study");
    }
    public void sleep()
    {
         System.out.println("坐着睡");
    }
}
————————————————
class AdvStudent extends Student
{
    public void study()
    {
        System.out.println(" adv study");
    }
}
————————————————
class  DuoTaiDemo3
{
    public static void main(String[] args) 
    {
        DoStudent ds = new DoStudent();
        ds.doSome(new BaseStudent());
        ds.doSome(new AdvStudent());
 
//        BaseStudent bs = new BaseStudent();
//        bs.study();
//        bs.sleep();
//        AdvStudent as = new AdvStudent();
//        as.study();
//        as.sleep();
    }
}
先看注释部分,由于基础班和高级班睡觉方式不同,
所以我要分别实例化,并调用学习,睡觉的方法
这样每次都调用学习,睡觉的方法,就会麻烦
那么,此时就可以通过DoStudent类去管理这些事
class DoStudent
{
    public void doSome(Student stu)
    {
        stu.study();
        stu.sleep();
    }
}
new一个DoStudent,然后调用doSome()方法
看,doSome方法参数是Student类型的,
但实例化的时候,我可以new avd,base
Student———>BaseStudent
这样,我就实现了向上转型
------------
上面的好处是什么呢,可以提高拓展性
当我想开设一个黑客班的时候,只需要黑客班继承抽象类
复写抽象类的方法,就可以用DoStudent来实例化了
----------------------------------------------------------------------------------
如下图,zi类继承了fu类的method1,method2方法,并复写了method1方法
现在Fu f = new Zi();
    f.method1();
    f.method2(); 
    //f.method3(); 如果加上这句,编译会失败的,因为编译看左边,左边是Fu,而Fu类中没有定义method3
而运行看右边,就是说,调用方法时,要看Zi类的方法
所以,上面运行结果是zi method_1;(子类复写的父类)
fu method_2;(子类继承的父类)
---------------------------------------------------
面试题
多态中,成员变量的特点:无论编译和运行,都参考左边
------------------------------------------
-------------------------------------------
参考左边的话,那么打印的第一行就会打印父类的num——>5
第二行就会打印子类的num——>8
----------------------------------------------
多态中,静态成员的特点,都参考左边(静态的方法,变量)
也就是说,子类重写父类的静态方法是不起作用的
---------------------------------------------------
看下面是方法区,里面的是静态方法区,和非静态方法区
--------------------------------------------------------------------------
实例
/*
需求:
电脑运行实例,
电脑运行基于主板。主板上插网卡,声卡,,,,
怎么插呢?通过PCI插槽这个标准
*/
————————————
怎么弄呢
首先,我要有一个主板,并把主板跑起来2
然后,我的主板上要有PCI插槽,所以定义usePCI( PCI p);
而PCI是一个标准,所以是接口
这样,我的主板的PCI插槽里,就可以插声卡,网卡了。。。
那我的声卡,网卡怎么定义呢,要遵循PCI标准,所以要实现PCI接口,并复写接口里的方法
class NetCard implements PCI{
run(){}
close(){}
}
然后看main函数中是怎么跑起来的:
先实例化一个主板,调用run方法让主板跑起来
  mb.usePCI(null);//这句代码会出错的,因为这里面是空引用,没有实例(修改后的代码已经有了判断,判断是否为空)
注意:调用usePCI(new NetCard),参数是网卡,但定义的参数是PCI接口,这是怎么回事呢
这是接口型引用指向自己的子类对象,而new的网卡实现了PCI接口(或者说标准)
粗暴点说就是:只要你按照我的标准做(实现接口),你做出来的东西(实例化),就能插进我主板(MainBoard)上的PCI插槽(usePCI)里
MainBoard mb = new MainBoard();
        mb.run();
        mb.usePCI(null);
        mb.usePCI(new NetCard());
 
 
————————————1
interface PCI
{
    public void open();
    public void close();
}
————————————2
class MainBoard
{
    public void run()
    {
        System.out.println("mainboard run ");
    }
    public void usePCI(PCI p)    //PCI p = new NetCard()// 接口型引用指向自己的子类对象。
    {
        if(p!=null)
        {
            p.open();
            p.close();
        }
    }
}
——————————————3
class NetCard implements PCI
{
    public void open()
    {
        System.out.println("netcard open");
    }
    public void close()
    {
        System.out.println("netcard close");
        method();
    }
}
——————————————4
class SoundCard implements PCI
{
    public void open()
    {
        System.out.println("SoundCard open");
    }
    public void close()
    {
        System.out.println("SoundCard close");
    }
}
————————————————5
class DuoTaiDemo5 
{
    public static void main(String[] args) 
    {
        MainBoard mb = new MainBoard();
        mb.run();
        mb.usePCI(null);
        mb.usePCI(new NetCard());
        mb.usePCI(new SoundCard());
 
    }
}
———————————————————————————————
实例
看截图,数据库的操作,我刚开始是使用JDBC连接数据库,并添加,删除数据的
可是多年之后,随着技术的发展,出现了新的连接数据库的技术Hibernate
那我可能就要根据需要,把所有的JDBC连接方式全改掉,这样的耦合性(粘性)太高了
那么该怎么办呢
思路是这样的,我可以定义一个标准(接口)UserInfoDao,而JDBC,Hibernate都是遵循这个标准的
这个例子我主要是说实例化的过程
UserInfoDao uid = new JDBC();这种形式
接口  uid  = new 类名();        这个类实现了这个接口
————————————————————
public class ExtendsDemo {
    public static void main(String[] args) {
    UserInfoDao uid = new JDBC();
    uid.add(new User());
    uid.delete(new User());
    }
}
————————————
class User{
    User(){
        System.out.println("new user sss");
    }
}
————————————
interface UserInfoDao
{
    void add(User user);
 
    void delete(User user);
}
————————————
class JDBC implements UserInfoDao{
    public void add(User user){System.out.println("JDBC,,,,ADD");}
    public void delete(User user){System.out.println("JDBC,,,DELETE");}
}
————————————
class Hibernate implements UserInfoDao{
    public void add(User user){System.out.println("Hibernate,,,,ADD");}
    public void delete(User user){System.out.println("Hibernate,,,DELETE");}
}
————————————
 
 

转载于:https://www.cnblogs.com/aisi-liu/p/4164417.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值