面向对象(多态+接口实现)-第18天

98_面向对象(多态-概念)

多态:可以理解事物存在的多种体现形态。

重载覆盖就是函数多态体现。

人:男人,女人。这就是人的多态。

 

动物:猫,狗

猫 x=new 猫();

动物 x=new 猫();
1,多态的基本体现

父类的引用指向了自己的子类对象。

2,多态的前提

必需是类与类之间有关系。要么继承,要么实现。

通常还有一个前提,存在覆盖。

3,多态的好处

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

多态的弊端:

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

4,多态的应用。

 

99_面向对象(多态-扩展性)

1,多态的基本体现

父类的引用指向了自己的子类对象。

父类的引用也可以接受自己的

动物:猫,狗。

class Animal

{

void eat()

{

}//错误,eat吃什么,不确定。

}

改成抽象:

abstract class Animal

{

public 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 DuoTaiDemo

{

public static void main(String[] args)

{

Cat c=new Cat();

c.eat();打印吃鱼。

Dog d=new Dog();

d.eat();打印吃骨头。

Cat c1=new Cat();

c1.eat();打印吃鱼。

Cat c2=new Cat();

c2.eat();打印吃鱼。

}

封装方法.eat()。

class DuoTaiDemo

{

public static void main(String[] args)

{

Cat c=new Cat();

Cat c1=new Cat();

function(c1);打印吃鱼。

function(new Dog());打印吃骨头

}

public static void function(Cat c)

{

c.eat();

}

public static void function(Dog d)

{

d.eat();

}

一年后,还有养猪。

abstract class Animal

{

public 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(拱地);

}

}

public static void function(Cat c)

{

c.eat();

}

public static void function(Dog d)

{

d.eat();

//添加了猪的吃。

public static void function(Pig p)

{

p.eat();

}

class DuoTaiDemo

{

public static void main(String[] args)

{

Cat c=new Cat();

Cat c1=new Cat();

function(c1);//打印吃鱼。

function(new Dog());//打印吃骨头

function(new Pig());//打印饲料

}

 

对比:

abstract class Animal

{

public 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(拱地);

}

}

public static void function(Cat c)

{

c.eat();

}

public static void function(Dog d)

{

d.eat();

//添加了猪的吃。

public static void function(Pig p)

{

p.eat();

}

class DuoTaiDemo

{

public static void main(String[] args)

{

Animal c=new Cat();//为什么可以这样呢???一个对象具备多种形态造成的。c是猫,也是动物。把动物变成了具体的猫。

c.eat(); //打印吃鱼。子类覆盖父类eat()

}

多态实例代码:

abstract class Animal {

    public 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("拱地");

    }


    public static void function(Animal a)//这时,变成了Animal a=new Cat()

    {

        a.eat();

    }
}

class Anim {

    public static void main(String[] args) {

        Pig.function(new Cat());//注意:不是function(new Cat);

        Pig.function(new Dog());//打印:吃骨头。

        Pig.function(new Pig());

    }
}

3,多态的好处

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

 

100_面向对象(多态-转型)

public class Anim {
    public static void main(String[] args) {
        Animal a = new Cat();
        a.eat();
//        类型提升。 byte b=1;int x=b;把猫提升为动物。向上转型。转成父类型。动物具备了猫的属性。
        Cat c = (Cat) a;//强制把动物转换成猫

        c.catchMouse();
    }
}

打印:

吃鱼

抓老鼠

 

人物举例:

毕姥爷 x=new 毕老师();毕老师变成了毕姥爷。

x.讲课();虽然变成了毕姥爷,但是运行的是毕老师讲课的内容,讲java内容。

毕老师 y=(毕老师)x;再把毕姥爷变回成毕老师。

y.看电影();然后毕老师可以陪朋友去看电影了。哈哈。。。

 

运用instanceof实例化来判断是不是属于该类。

public class Anim {
    public static void main(String[] args) {
        Pig.function(new Cat());
        Pig.function(new Dog());
    }
}

abstract class Animal {

    public 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("拱地");
    }

    public static void function(Animal a)//这时,变成了Animal a=new Cat()
    {
        a.eat();
        if (a instanceof Animal)//a的实例化是Cat吗?a属于Animal吗?
        {
            System.out.println("haha");
        } else if (a instanceof Cat)//a的实例化是Cat吗?
        {
            Cat c = (Cat) a;
            c.catchMouse();
        } else if (a instanceof Dog)//a的实例化是Dog吗?
        {
            Dog c = (Dog) a;
            c.kanJia();
        }
    }
}

打印:

吃骨头

haha

看家

haha

 

 

102_面向对象(多态中成员的特点)

 

重点!!!

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

在编译时期:查阅引用型变量所属的类中是否有调用的方法。如果有,编译通过。

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

简单总结就是:成员函数在多态调用时,编译看左边,运行看右边。

public class Anim {
    public static void main(String[] args) {
        Zi z = new Zi();

        z.method1();//zi method_1

        z.method2();//fu method_2

        z.method3();//zi method_3
    }
}

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");//Zi_1把父类的Zi_1覆盖了。

    }

    void method3() {

        System.out.println("zi method_3");

    }

}

对比:

class DuoTaiDemo

{

public static void main(String[] args)

{

Fu f=new Zi();//父类引用子类

f.mothod1();//zi method_1。编译通过,父类有该方法;运行看右边,结果是子类的

f.mothod2();//fu method_2

}

}

 

对比:

class DuoTaiDemo

{

public static void main(String[] args)

{

Fu f=new Zi();

f.mothod1();

f.mothod2();

f.mothod3();//编译失败。编译的时候对象Zi还没产生,系统会Fu中,发现没有mothod3.

}

}

 

面试用:

在多态中,成员变量的特点:

无论编译和运行,都参考左边(引用型变量所属的类)。

public class Anim {
    public static void main(String[] args) {
        Fu f = new Zi();

        System.out.println(f.num);//打印是父类的num=5,成员变量没有覆盖操作

        Zi z = new Zi();

        System.out.println(z.num);
    }
}

class Fu {
    int num = 5;//成员变量num=5

    void method1() {

        System.out.println("fu method_1");

    }

    void method2() {

        System.out.println("fu method_2");

    }

}

class Zi extends Fu {
    int num = 8;

    void method1() {

        System.out.println("zi method_1");//Zi_1把父类的Zi_1覆盖了。

    }

    void method3() {

        System.out.println("zi method_3");

    }

}

打印:

5

8

 

面试用:

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

无论编译和运行,都参考左边。静态随着类加载

public class Anim {
    public static void main(String[] args) {
        Fu f = new Zi();

        System.out.println(f.num);//打印是父类的num=5,num对象也是静态的
        f.method1();//fu method_1。mothod的是静态,f.mothod1()相当于类.静态方法,就是类名调用。
        Zi z = new Zi();
        System.out.println(z.num);
    }
}

class Fu {
    static int num = 5;//成员变量num=5

    static void method1() {

        System.out.println("fu method_1");

    }

    void method2() {

        System.out.println("fu method_2");

    }
}

class Zi extends Fu {
    int num = 8;

    static void method1() {

        System.out.println("zi method_1");//Zi_1把父类的Zi_1覆盖了。

    }

    void method3() {

        System.out.println("zi method_3");

    }

}

打印:

5
fu method_1
8

 

103_面向对象(多态的主板示例)

需求:

电脑运行实例,

电脑运行基于主板。

主板要实现多功能

public class Anim {
    public static void main(String[] args) {
        MainBoard mb=new MainBoard();

        mb.run();

        mb.usePCI(null);//这句自动跳过

        mb.usePCI(new NetCard());//mb.usePCI.NetCard(),为什么不可以这样?NetCard没有被public修饰
    }
}

interface 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 NetCard()。接口型引用指向自己的子类对象。

    {

        if (p != null)//检测插槽是否为空。

        {

            p.open();

            p.close();

        }

    }

}

class NetCard implements PCI//implements实现端口      

{

    public void open()//覆盖了父类方法

    {

        System.out.println("netcard open");

    }

    public void close() {

        System.out.println("netcard close");

    }

}

打印:

mainboard run

netcard open

netcard close

 

 

104_面向对象(多态的扩展示例)

需求:数据库的操作。

数据是:用户信息。

1,连接数据库JDBC Hinernate

2,操作数据库。

c create r read u update d delete

3,关闭数据库连接。

 

class UserInfoByJDBC

{

pulic void add(User user)

{

1,JDBC连接数据库。;

2,使用sql添加语句添加数据。;

3,关闭连接。

}

pulic void delete(User user)

{

1,连JDBC接数据库。;

2,使用sql添加语句删除数据。;

3,关闭连接。

}

}

class DBOperate

{

public static void main(String[] args)

{

UserInfoByJDBC ui =new UserInfoByJDBC();

ui.add(user);

ui.delete(user);

}

}

 

通过Hibernate连接。

class UserInfoByHibernate

{

pulic void add(User user)

{

1,Hibernate连接数据库。;

2,使用sql添加语句添加数据。;

3,关闭连接。

}

pulic void delete(User user)

{

1,Hibernate接数据库。;

2,使用sql添加语句删除数据。;

3,关闭连接。

}

}

class DBOperate

{

public static void main(String[] args)

{

UserInfoByHibernate ui =newUserInfoByHibernate();

ui.add(user);

ui.delete(user);

}

}

 

两次变化,主函数都需要改变ui的变量类型。如何降低耦合性。?

interface UserInfoDao//接口

{

public void add(User user);

public void delete(User user);

}

class UserInfoByJDBC implements UserInfoDao

{

pulic void add(User user)//覆盖接口

{

1,JDBC连接数据库。;

2,使用sql添加语句添加数据。;

3,关闭连接。

}

pulic void delete(User user)

{

1,连JDBC接数据库。;

2,使用sql添加语句删除数据。;

3,关闭连接。

}

}

class DBOperate

{

public static void main(String[] args)

{

UserInfoDao ui=new UserInfoByJDBC();

ui.add(user);

ui.delete(user);

}

}

 

 

105_面向对象(Object类-equals())

object是所有对象的直接后者间接父类,传说中的上帝。

该类中定义的肯定是所有对象都具备的功能。

class Demo//隐藏了extends object

{

Demo()

{

//隐藏了super();

}

java中,任何对象具比较两个对象是否相同的功能:equals

其实equals其实相当于比较地址值

class Demo

{

}

class ObjectDemo

{

public static void main(Stringp[] args)

{

Demo d1=new Demo();

Demo d2=new Demo();

Demod3=d1;//d3是媒介

System.out.println(d1.equals(d2));//打印false

System.out.println(d1.equals(d3));//打印true。这个equals接受的是Demo类型

System.out.println(d1==d2);//打印false。其实equals其实相当于比较地址值。

System.out.println(d1==d3);//打印true



Person p1=new Person();

Person p2=new Person();

system.out.println(people+p1.equals(p2));打印people:true。这个equals接受是Person类型

}

}

}

Person类型和Demo类型都是object的子民。

equals(Object obj)定义object的类型,故它的子民都是可以调用它。

class Demo

{

private int num;

Demo(int num)//构造函数

{

this.num=num;

}

public boolean compare(Demo d)

{

return this.num==d.num;//比较的是数值,而不是地址。

}

}

class ObjectDemo

{

public static void main(Stringp[] args)

{

Demo d1=new Demo(4);

Demo d2=new Demo(6);

System.out.println(d1.compare(d2));//false

}

}

}

Object中已经提了对对象是否相同的比较方法。

如果自定义类中也有比较相同的功能时,没有必要重新定义。

只要沿袭父类中的功能,建立自己特有比较内容即可。这就是覆盖

class Demo

{

private int num;

Demo(int num)

{

this.num=num;

}

public boolean equals(Object obj)

{

return this.num==obj.num;//变量num在Object的类中,找不到。

}

class ObjectDemo

{

public static void main(Stringp[] args)

{

Demo d1=new Demo(4);

Demo d2=new Demo(6);

System.out.println(d1.equals(d2));//编译错误。

}

}

}

对比:

class Demo

{

private int num;

Demo(int num)

{

this.num=num;

}

public boolean equals(Object obj)
//此时把Object obj=d2;相当于Object obj=new Demo();这时相当于多态的表现形式。

{

Demo d=(Demo)obj;//把上帝类Object的obj对象,强制转换为Demo型

return this.num==d.num;//这时,就可以调用d.num

}

class ObjectDemo

{

public static void main(Stringp[] args)

{

Demo d1=new Demo(4);

Demo d2=new Demo(4);

System.out.println(d1.equals(d2));//打印true

}

}

类型转换异常

class Demo

{

private int num;

Demo(int num)

{

this.num=num;

}

public boolean equals(Object obj)

{

Demo d=(Demo)obj;

return this.num==d.num;

}

class ObjectDemo

{

public static void main(Stringp[] args)

{

Demo d1=new Demo(4);

Demo d2=new Demo(5);

Person p=new Person();

System.out.println(d1.equals(p));//运行报错。ClassCastException类型转换异常。

}

}

instanceof 判断类型

class Demo

{

private int num;

Demo(int num)

{

this.num=num;

}

public boolean equals(Object obj)

{

if(!(obj instanceof Demo))//instanceof obj指向的是Demo吗?不是,返回false

return false;

Demo d=(Demo)obj;

return this.num==d.num;  

}

class ObjectDemo

{

public static void main(String p[] args)

{

Demo d1=new Demo(4);

Demo d2=new Demo(5);

Person p=new Person();

System.out.println(d1.equals(p));//打印false

}

}

 

106_面向对象(Object类toString())

toString()函数:默认返回的内容是“对象所属的类名+@+对象的哈希值(十六进制)”

Object中有专门打印哈希值的函数hashCode()

class Demo{}

class ObjectDemo

{

public static void main(Stringp[] args)

{

Demo d1=new Demo();

Class c=d1.getClass();//c获取d1对象所属的类Demo

//c.getName()返回c的名称,Integer.toHexString(d1.hashCode())这个对象的哈希值强制转换为16进制

System.out.println(c.getName()+@+Integer.toHexString(d1.hashCode()));//打印Demo@c17164

System.out.println(d1.toString);//Demo@c17164

}}

总结:

toString()相当于

getClass().getName() + '@' +Integer.toHexString(hashCode())

 

重写toString

public class PackageOne {
    public static void main(String[] args) {
        System.out.println(new ToStringDemo().toString());//tostring
    }
}

class ToStringDemo{
    //重写(覆盖)原来的toString()
    @Override
    public String toString() {
        return "tostring";
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值