面对对象的多态性、 Object类和equals()方法

多态性的使用

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

利用如下类进行示范

public class Person
{
    private String name;
    private int age = 1;
    private boolean isMale;
    public void eat()
    {
        System.out.println("人可以吃饭");
    }
    public void sleep()
    {
        System.out.println("人可以睡觉");
    }
    public void talk(String language)
    {
        System.out.println("人可以说话,使用的是:"+language);
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public boolean isMale() {
        return isMale;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public void setMale(boolean male) {
        isMale = male;
    }
};
class Chinese extends Person{
    private String nation;

    public void setNation(String nation) {
        this.nation = nation;
    }

    public String getNation() {
        return nation;
    }

    public void sleep()
    {
        System.out.println("中国人会睡觉");
    }

    public void eat()
    {
        System.out.println("中国人会睡觉");
    }

    public void talk(String language)
    {
        System.out.println("中国人可以说话,说的是"+ language);
    }
}

测试代码如下

public class Persontext
{
    public static void main(String[] args)
    {
        Chinese c1 = new Chinese();
        c1.sleep();
        c1.eat();

        System.out.println("******************************");

        Person p1=new Person();
        p1.sleep();
        p1.eat();

        System.out.println("******************************");

        Person p2=new Chinese();
        p2.sleep();
        p2.eat();
    }
};

结果如下

 明明是声明为Person类的对象,却是new了一个Chinese,也可以调用Chinese中重写的方法,但是不可以调用Person中没有的属性和方法,Chinese中之后定义的属性和方法,比如说在本例中,p2如果不进行强制转化,就不可以利用setNation和getNation,也不可以直接引用nation这个属性

本质上p2依旧是Person类,仅仅是能利用重写的方法

但是在编译期间,其实本质上Person类依旧是加载的Person类里面自己声明的方法,但是在运行期间就会使用Chinese中对同名方法的重写

编译就看左边,运行要看右边

多态性使用前提

1、有类的继承关系

2、有方法的重写

子类中定义了父类同名同参的方法,在多态情况下,将此时父类的方法称为虚拟方法,父类根据赋给他不同子类的对象,动态调用子类的方法

多态是运行时行为,编译的时候不体现多态(动态绑定)

重载是早绑定,重写是晚绑定

在这里额外提一下重载和重写

重载在编译的时候,已经确定了要执行的方法,但是重写的方法要在运行的时候才能确定,如果是晚绑定,才能体现多态性,早绑定并不是多态性

instanceof函数

x instanceof A:检验x是否是类A的对象(x为对象,A为类),返回值为boolean类型的数据

public class Persontext
{
    public static void main(String[] args) {
        Chinese c1 = new Chinese();

        Person p1 = new Person();

        Person p2 = new Chinese();

        System.out.println(p1 instanceof Chinese);
        System.out.println(c1 instanceof Person);
        System.out.println(p2 instanceof Chinese);
    }
};

结果

 可以看出来,在这里c1可以是Person的对象,因为Chinese和Person子父类关系,但是p1不可能是Chinese的对象,因为Person是Chinese的父类,但是由于p2利用了多态性,所以p2也可以说是Chinese的对象

如果父类想要强行调用子类特有的属性和方法,就需要提到另一个方法

强制转化

为了使用向下转型,防止出现异常,在转型之前先进行instanceof的判断,但是仍有一个问题,无法判断谁是谁的父类

比如

public class Persontext
{
    public static void main(String[] args) {
        
        Chinese c1 = new Chinese();
        
        System.out.println(c1 instanceof Chinese);
        System.out.println(c1 instanceof Person);
    }
};

结果

如此图,二者的结果都是true,根本上我们是由于创建的过程才知道的Person是Chinese的父类,但是如果只看instanceof返回的结果,我们仍然无法对子父类关系进行精准的判断 ,而这里还有一个误区就是关于“==”这个符号在对象的比较中,实际上是比较二者的地址,并不能起到什么实质性的作用

Object类

1、Object类是根父类,如果一个类没有声明父类,那么默认它的父类是Object类

2、getClass(),getSuperclass()可以获取类的父类

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

        Chinese c1 = new Chinese();
        Person p1 = new Person();

        System.out.println(c1.getClass());
        System.out.println(p1.getClass());
    }
};

 结果如下

 3、Object类中的方法具有通用性, Object类没有属性

4、 Object类只声明了一个空参构造器

此处区分一个函数和“==”

“==”

是一个运算符,在基本数据类型和引用数据类型中都可以使用(boolean不可以使用)

而且“==”会对基本数据类型进行自动提升

1、“==”比较基本数据类型的时候,会比较其中所存的数据是否相等

2、“==”一旦比较引用类型的话,只会比较地址值是否相等

equals()方法的使用

equals()只适用于引用数据类型

1、 Object类中对equals()的的定义与“==”符号的作用相同,都是比较地址值

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

        Chinese c1 = new Chinese();
        Chinese c2 = new Chinese();

        System.out.println(c2.equals(c1));

//由于两者实际上地址一定是不同的,所以此处就会返回flase

        c1=c2;

//之前说过对于对象而言,“==”是传址操作,所以这里就是把c2的地址赋给了c1

        System.out.println(c2.equals(c1));

//在这里再次判断的时候,结果就是true
    }
};

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

3、如果直接调用那就是比较地址值,如果想使用equals()去比较实体内容的话,就要将equals()重写,但是目前的部分编译器对与equals()是可以自动生成的

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值