Java基础-08-面向对象(续3)

Java基础-面向对象

面向对象入门(续)

1、面向对象(多态--概念)

(1)、多态:可以理解为事物存在的多种体现形式。 例如:

人:男人、女人。 动物:猫、狗。

Eg:

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

(2)、特征

  • 多态的基本体现:父类的引用指向了自己的子类对象。父类的引用也可以接收自己的子类对象。
  • 多态的前提:必须是类与类之间有关系。要么继承,要么实现,还有一个前提:存在覆盖。
  • 多态的好处:大大提高了程序的扩展性。(弊端:但是只能使用父类的引用访问父类中的成员。)
  • 多态的应用:

    /*
     *动物
     *猫、狗 
     * */
    abstract class Animal        //抽象类Animal
    {
        abstract void eat();        //抽象方法
    }
    
    class Cat extends Animal            //类Cat继承抽象类Animal
    {
        public void eat()
        {
            System.out.println("吃鱼");        //方法覆盖
        }
        public void catchMouse()
        {
            System.out.println("抓老鼠");        
        }
    }
    
    class Dog extends Animal            //类Dog继承抽象类Animal
    {
        public void eat()
        {
            System.out.println("吃骨头");    //方法覆盖
        }
        public void kanjia()
        {
            System.out.println("看家");
        }
    }
    
    class Pig extends Animal            //类Pig继承抽象类Animal
    {
        public void eat()
        {
            System.out.println("饲料");        //方法覆盖
        }
        public void gongDi()
        {
            System.out.println("拱地");
        }
    }
    
    class DuoTaiDemo            //主函数
    {
        public static void  main(String[]args)
        {
            Cat c = new Cat();        
            c.eat();
            Dog d = new Dog();
            d.eat();
            function(c);        //对象作为函数参数用来传递
            function(d);        //多态体现。d为Dog类型,传到function(Animal a)里,进行实现多态功能
            function(new Pig());//同样进行多态实现功能。
            Animal c1 = new Cat();//类型提升,也是多态的表现。
            c1.eat();
        }
        public static void function(Cat c)
        {
            c.eat();
        }
        public static void function(Animal a)        //用父类Animal类的对象作为函数接收参数的类型,用来体现多态机制,提高代码复用性。
        {
            a.eat();
        }
    }
    

输出结果:

吃鱼
吃骨头
吃鱼
吃骨头
饲料
吃鱼

2、面向对象(多态--转型)

前例中的 Animal a = new Cat(); 我们称为类型提升,也叫向上转型。

如果想要调用猫的特有方法时,如何操作? 强制将父类的引用,转成子类类型,称作向下转型。 例如:

Cat c = (Cat) a ;
c.catchMouse;

但如果这样的话,错误:

Animal a = new Animal();
Cat c = (Cat) a;

千万不要出现以上这样的操作,就是将父类对象转成子类类型,我们能转换的是父类应用指向了自己的子类对象时,该应用可以被提升,也可以被强制转换,多态自始至终都是子类对象在做着变化。

3、面向对象(多态成员中的特点)

Eg:
class Fu
{
    void method_1()
    {
        System.out.println("Fu method_1");
    }
    void method_2()
    {
        System.out.println("Fu method_2");
    }
}
class Zi extends Fu
{
    void method_1()
    {
        System.out.println("Zi method_1");
    }
    void method_3()
    {
        System.out.println("Zi method_3");
    }
}
class DuoTaiDemo4
{
    public static void main(String[]args)
    {
        Zi z = new Zi();
        z.method_1();    //输出Zi method_1
        z.method_2();    //输出Fu method_2
        z.method_3();    //输出Zi method_3

        Fu f = new Fu();    
        f.method_1();    //输出Zi method_1
        f.method_2();    //输出Fu method_2
        f.method_3();    //输出错误
    }
}

在多态中成员函数的特点:

(1)在编译时期:参阅引用型变量所属的类中是否有调用的方法,如果有,编译通过,如果没有编译失败。
(2)在运行时期:在参阅对象所阅的类中是否有调用的方法。
简单总结就是:成员函数在多态调用时,编译看左边,运行看右边。

另一个例子:

class Fu 
{
    int num = 5;
}
class Zi extends Fu
{
    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

在多态中,成员变量的特点:无论编译和运行,都参看左边(引用型变量所属的类)

例:

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

程序结果:

Fu method_1
Zi method_1

在多态中,静态成员函数特点: 无论编译还是运行,都参考左边。

4、面向对象(多态的主板示例)

实际小应用

/*
 * 需求:
 * 电脑运行示例。电脑运行基于主板*/
 //未运用多态机制编写的代码,即未改善的代码
class MainBoard            //主板
{
    public void run()        //启动主板
    {
        System.out.println("mainboard run");
    }
    public void useNetCard(NetCard c)        //主板上的功能,使用网卡(网卡插入)
    {
        c.open();
        c.close();
    }
}
class NetCard        //网卡
{
    public void open()        //打开网卡
    {
        System.out.println("netcard open");
    }
    public void close()        //关闭网卡
    {
        System.out.println("netcard close");
    }
}
class DuoTaiDemo5
{
    public static void main(String[]args)
    {
        MainBoard mb = new MainBoard();        //新建主板对象
        mb.run();        //运行主板(主板通电)
        mb.useNetCard(new NetCard());     //启动主板上的使用网卡功能,并把网卡插入到主板中
    }
}

程序输出结果:

mainboard run
netcard open
netcard close

但以上代码类与类之间耦合性太强。实际中电脑主板与各硬件之间联系的藕带还有一个关键的接口(PCI),如图:

改善后的代码: Eg:

interface PCI        //PCI接口
{
    public void open();        //抽象功能
    public void close();    //抽象功能
}
class MainBoard        //主板类
{
    public void run()        //功能,启动主板
    {
        System.out.println("mainboard run!");
    }
    public void usePCI(PCI p)    //PCI p = new NewCard(); 这是接口型引用指向自己的子类对象
    {
        if(p!=null)
        {
            p.open();
            p.close();
        }
    }
}
class NetCard implements PCI        //网卡实现PCI接口
{
    public void open()        //功能覆盖,启动网卡
    {
        System.out.println("netcard open!");
    }
    public void close()        //功能覆盖,关闭网卡
    {
        System.out.println("netcard close!");
    }
}
class SoundCard implements PCI        //声卡实现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);        //
        mb.usePCI(new NetCard());        //在PCI上插入网卡
        mb.usePCI(new SoundCard());        //在PCI上插入声卡

    }
}

程序结果:

mainboard run!
netcard open!
netcard close!
soundcard open!
soundcard close!

5、面向对象(多态的扩展示例)

以下一段关于数据库操作的伪代码:

/*
 *需求:数据库的操作
 *1、连接数据库。JDBC、Hibernate
 *2、操作数据库:creat、read、update、delete
 *3、关闭数据库连接。
 * */
class UserInfoByJDBC
{
    public void add(User user)
    {
        1、连接数据库
        2、使用sql添加语句添加数据
        3、关闭连接
    }
    public void delete(User user)
    {
        1、连接数据库
        2、使用sql添加语句删除数据
        3、关闭连接
    }
}
class DBOperate
{
    public static void main(String[]args)
    {
        UserInfoByJDBC ui = new UserInfoByJDBC();
        ui.add(user);
        ui.delete(user);
    }

}

通过观察以上的伪代码我们可以发现问题:若我们不想用JDBC连接数据库,而是Hibernate连接,那么我们又要定义一个新的UserInfoByHibernate类,麻烦,这样设计程序耦合性太强,没考虑到程序的扩展性。

如图:

然而,我们考虑一种新的方法来解决程序类之间的耦合性差问题,增加程序的扩展性。 我们引用一个Dao(date access object)方法,如图:

以下是伪代码: Eg:

interface UserInfoDao
{
    public void add(User user);
    public void delete(User user);
}
class UserInfoByJDBC implements UserInfoDao
{
    1、连接数据库
    2、使用sql添加语句删除数据
    3、关闭连接
}
class UserInfoByHibernate implements UserInfoDao
{
    1、连接数据库
    2、使用sql添加语句删除数据
    3、关闭连接
}
class DBOperate
{
    public static void main(String[]args)
    {
        UserInfoDao ui = new UserInfoByHibernate();
        UserInfoDao ui_1 = new UserInfoByJDBC();
        ui.add(user);
        ui.delete(user);
        ui_1.add(user);
        ui_1.delete(user);

    }
} 

6、面向对象(Object类 ----equal())

Object类:是所有对象的直接或者间接父类,传说中的上帝,该类中定义的肯定是所有对象都具备的功能。

Eg:

class Demo  //extends Object
{

}
class ObjectDemo
{
    public static void main(String[]args)
    {
        Demo d1 = new Demo();
        Demo d2 = new Demo();
        System.out.println(d1.equals(d2));        //d1对象引用equals()方法去比较自己和对象d2是否为同一个对象。其实就是比较是否是同一地址。
    }
}

程序结果:false

Object类中已经提供了对对象是否相同的比较方法equal (),如果自定义类中也有比较相同的功能,没有必要重新定义, 只要沿袭父类中的功能,建立自己特有比较内容即可,也就是覆盖。 Eg:

class Demo
{
    private int num ;
    Demo(int num)
    {
        this.num = num ;
    }
    public boolean equals(Object obj)    //复写
    {
        if(!(obj instanceof Demo))
        {
            return false;
        }
        else 
        {
            Demo d = (Demo) obj;    //向下转换
            return this.num == d.num;
        }
    }
}
class Person
{

}
class ObjectDemo
{
    public static void main(String[]args)
    {
        Demo d1 = new Demo(4);
        Demo d2 = new Demo (4);
        Person p = new Person();
        System.out.println(d1.equals(d2));
        System.out.println(d1.equals(p));
    }
}

程序结果:

true
false
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值