Java 快速入门 知识精简(4)面向对象-多态

多态性

理解多态性:可以理解为一个事物的多种形态。

对象的多态性:

父类的引用指向子类的对象

(或子类的对象赋给父类的引用)


示例:

Person p1 = new Person( );

Person p2 = new Man( );          // 对象的多态性  Man继承Person

多态的使用:

父类的引用调用同名同参数的方法时(重写方法),实际执行的是子类重写父类的方法 —— 虚拟方法调用


示例:

Man man = new Man();  // 创建的对象

man.eat();

p2.eat();                          // 编译时看左边,运行时看右边

有了对象的多态性以后,我们在编译时,只能调用父类中声明的方法,但在运行时,实际执行的是子类重写父类的方法。

实例:

public class Animal {

    public static void main (String[] args){

        Animal test = new Animal();

        test.func(new Dog());
        // 运行结果: 狗 爱吃火腿  汪汪汪!

    }

    public void func(Animal animal){

        animal.eat();

        animal.shout();

    }

    public void eat(){

        System.out.println("动物吃饭");

    }

    public void shout(){

        System.out.println("动物叫声");
        
    }
}

class Dog extends Animal{

    public void eat(){

        System.out.println("狗 爱吃火腿");

    }

    public void shout(){

        System.out.println("汪汪汪!");
        
    }

}

多态性的使用前提:

①类的继承关系

②方法的重写

说明

1)对象的多态性只适用于方法,属性不具有多态性

2)父类与子类中的同名属性是共存的,在编译时就已经确定(编译与运行都看左边),所以不具有多态性

实例


public class Test{
    public static void main(String[] args) {

        Animal myDog = new Dog();    // 多态: 父类引用指向子类对象

        System.out.println(myDog.makeSound()); // 运行结果: 汪汪汪

        System.out.println(myDog.sound); // 运行结果: 动物叫声

    }
}
// 父类
class Animal {

    public String sound = "动物叫声";
    
    public String makeSound() {
        return sound;
    }
}
// 子类
class Dog extends Animal {

    public String sound = "汪汪汪";
    
    @Override
    public String makeSound() {
        return sound;
    }
}

instanceof关键字

如何调用子类特有的属性和方法:

向下转型:使用强制类型转换符。

Man m1 = (Man)p2;        // 强制类型转换   p2是Person类的引用,Man继承Person

m1.earnMoney( );

说明

1)使用强制转换时,可能出现ClassCastException的异常。

2)不相干的两个类不能转换

示例:

Women w1 = (Women)m1;        // 异常 ClassCastException

w1.goShopping( );

instanceof 关键字的使用:

a instanceof

说明

1)判断对象a是否是类A的实例

2)如果是,返回true

3)如果不是,返回false

示例

if (p2 instanceof Man){

        Man m2 = (Man) p2;

        m2.earnMoney( );

        System.out.print("man");

}

使用情景

为了避免在向下转型时出现ClassCastException的异常, 我们在向下转型时,先进行instanceof的判断,一旦返回true, 就向下转型,如果返回false,就不进行转型。

说明

1)a instanceof A 返回 true

2)B是A的父类,则 a instanceof B 也返回 true

示例

void getPrice(Computer com){
    // instanceof  判断对象是否属于这个类
    if(com instanceof NotePad){
        NotePad n = (NotePad)com;  // 造型  引用间的类型转换(继承关系)
        n.navigation();                        // 通过将父类转为子类,子类引用-子类特有的方法

说明

1)父类 Computer ,子类 NotePad

2)父类引用 com ,子类引用 n

// 创建对象
Computer com = new Computer();
NotePad notePad =
new NotePad();
// 多态的使用 多态参数方法
test.getPrice(com);
test.getPrice(notePad);

Object类

java.lang.Object类

1)Object类是所有java类的根父类

2)如果在类的声明未使用extends关键字指明其父类,则默认父类为java.lang.Obect类。

3)Object类中的功能(属性、方法)具有通用性。

Object类

属性:无属性

方法:

equals( )、toString( )、getClass( )、hashCode( )、clone( )

wait( )、notify( )、notifyALL( )、finalize( ) 

构造器:Object类只声明了一个空参的构造器

方法名称

类型

描述

public Object( )

构造

构造器

public boolean equals( Object obj)

普通

对象比较

public int hashCode( )

普通

取得hash码

public String toString( )

普通

对象打印时调时

问题:final、finally、finalize的区别?

1)final是一个修饰符,可以用来修饰方法和变量

  •         修饰类,表示类不能被继承
    •         修饰方法,表示方法不能被子类覆盖
      •         修饰变量,表示变量不能被修改,即常量

2)finally是Java异常处理的一个组成部分,与trycatch一起使用,表示即使发生异常时,一定会执行finally代码块中的代码

3)finalize在Java 12中被完全移除

问题== 与 equals 的区别

1)==

        == 可以比较基本数据类型:比较变量的“

        也可以比较引用类型:比较对象的“内存地址

2)equals

        具体要看自定义类里有没有重写Object类的equals 方法来判断

        如果该方法没有被重写,也默认是==

        如果重写equals方法,来比较类的相应属性是否都相等

equals( ) 方法的使用

说明

只适用于引用数据类型

Object 类中equals( ) 的定义

public boolean equals( Object obj ){

        return (this == obj);

}

说明

1)Object类中定义的equals( )方法和==作用是相同的,比较俩个对象的地址值是否相同

2)String、Date、File、包装类等都重写了Object类中的equals( )方法

重写:比较俩个对象的“实体内容”是否相等。

例:重写方法

@Override

public boolean equals (Object obj){

        if ( this ==obj){

                return true;

        }

        if( obj instanceof Customer){

                Customer cust = (Customer) obj;         // 造型  类型转换

        // 比较俩个属性是否都相等

                // 写法一:age 实参

                if( this.age == cust.age && this.name.equals( cust.name)){

                        return true;

                }else{

                        return false;

                }

                // 写法二:

                return this.age == cust.age&&this.name.equals(cust.name);

        }

        return false;

}

toString( )方法的使用

当我们输出一个对象的引用时,实际上就是调用对象的toString( )

示例:

System.out.print(a);

System.out.print(a.toString);

// 以上两个结果是相同的

Object类中toString( )的定义:

public String toString ( ){

        return getClass( ).getName( )+@+Integer.toHexString(hashCode( ));

}

说明

1)String、Date、File、包装类等都重写了Object类中的toString( )方法。使得在调用对象的toString( )时,返回“实体信息”。

自定义类也可以重写toString( )方法,当调用此方法时,返回对象的“实体内容”。

例:

@Override

public String toString(){

        return year+"年"+month+"月"+day+"日";

}

hashCode( ) 方法的使用

public int hashCode( ):

返回当前调用对象的哈希码

哈希码:

(1) 也称为散列码,不同的对象在内存中分布的散列性

(2) 也称为特征码,让所有属性数据参与运算的结果码值

它是根据对象的内存中的物理地址经过哈希算法,得出的一个码值

@Override                         // 重写  所有属性都要参与,计算过程要有变化性

public int hashCode( ){

        return 31*(x*7+y*23);         // x,y是当前对象的属性

}

多态数组

大大提升兼容性,处理不同类型的对象

示例:

Person[ ] arr = new Person[5];

arr[0] = new Chinese( );

arr[1] = new American( );

多态参数方法

1)多态参数方法,可以接收任意本类及子类对象;

2)会导致对象的类型模糊

例:

test( Person p){

        Chinese c = (Chinese) p ; // 造型  引用间的类型转换
}

test( Chinese c){

}

test( American ){

}

  • 24
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Tangy范

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值