[java核心外篇]__Object类与对象类型的转型

  • 前言
    我们在之前的学习中提过很多次了,java是面向对象的,java的基础可以说是建立在类和对象上面的.然后我们又学到了类的继承,发现了在java类库中,类的继承是极为普遍的,一个类继承另一个类,就像是一个家族树一样蔓延开来,今天就说一下,这个树的顶端,也就是一切类的开始,Object类.另外在学习下应继承机制而导致对象的两种特性.

  • Object类

Object类是JAVA语言一切类的开始,所有的类都直接或间接的继承自它,当我们定义一个类时,如果不声明继承关系,那么它就默认的继承Object类,因为它可以说是java语言一切类的父类,所以继承它就是默认的情况,使得我们在定义类的时候并不用通过extends指明和它的继承关系.但是我们又可以使用和重写它的一些基本的方法.

  • Object类中主要包括clone(),finalze(),equals(),toString()等方法.其中equlas方法和toString方法经常会被我们用到,并且会碰到重写toString方法的情况.

2019-4-11-09.gif

  • 我们在IdEA中通过定义两个类,我们可以就可以发现这一现象,最后打开Object类看看,可以看到其构成十分简单,只有少数基本的方法,虽然很多我们都没有用过,或许也不知道其作用.

image.png

这里需要注意到的是,Object类中的方法并不是都能够被重写的,因为其中有getClass(),notify(),notifyAll(),wait()等方法是被inal修饰符修饰的.我们知道被final修饰的变量是常量,所以被final修饰的方法也是一个"常量"方法,其内容是不可变的,也就意味着不能够被重写.

  • 其中getClass方法会返回对象执行的class实例,然后使用该实例调用getName方法可以获得类的名称.

我们试试看:

通过其方法的说明,我们可以这样使用它,打印出实例化对象所对应的类的类名.

System.out.println(sty_classfeature.getClass().getName());

image.png

  • toString方法,相比我们已经很熟悉了,它能够将对象的内容作为字符串类型返回.所以我们通常使用该方法来进行对象的输出.同时我们也可以对它进行重写.

我们可以看看Object类中的toString方法:

  public String toString() {
        return getClass().getName() + "@" + Integer.toHexString(hashCode());
    }

发现我们只能看得懂前半段,知道会返回一个对象对应的类名,@后面的应该是一个Int型的数据.经过查找一番,知道了后半段的意义:

在Object类中定义toString()方法的时候返回对象的哈希code码(对象地址字符串)

试试看:

// toString 方法
    System.out.println(sty_classfeature.toString());

image.png

现在我们知道了Object类的toString方法返回的值是这样的结构了,但显然,这和我们平时使用的toString方法不同啊,我们印象中的toString方法,应该是返回对象的一些属性值的,可以做出输出来使用的,是在哪里经常遇到的呢,看下面这段代码:

public class sty_entity {
    private String name;
    private int age;
    private char sex;

    @Override
    public String toString() {
        return "sty_entity{" + "name='" + name + '\'' + ", age=" + age + ", sex=" + sex + '}';
    }
}

image.png

对的没错,就是在我们构建实体类时会使用到的toString方法,然而其实这里使用的就是重写的toString方法,然后我们在其他类中实例化对象调用toString方法时,就可以返回将各属性以String类型返回了.

  • 对象的类型转换

对象的类型转换在java编程中也会经常遇到,包括有向上转型和向下转型.

  • 向上转型

向上转型就是将子类的对象赋值个父类,成为父类的一个实例化对象,这个其实是十分好理解的,我们前面了解到继承,知道了子类其实继承了父类的属性和行为,那么子类的对象自然也可以看做是一个(特殊的)父类的对象.就比如我们经常说的,正方形是一个特殊的平行四边形.

我们可以来看看这个例子:

public class sty_Typeconversion {
    public void main(String[] args) {  //定义主方法
        square square = new square();  // 实例化正方形对象
        square.draw(square); // 调用父类方法,以子类对象作为父类对象传参数,向上转型.
    }
}
// 定义四边形类
class quadrilateral{
   public void draw(quadrilateral q){
       System.out.println("绘制四边形");
    }
}
// 定义子类正方形继承四边形类
class square extends quadrilateral {
}

这里的我们子类没有重写父类方法draw,直接调用父类方法,而其参数必须是一个父类类型的参数,这里就把子类类型的对象当做了父类类型的参数使用,就是向上转型.

  • 向下转型

向下转型,就名字而言就明白了,它应该是和向上转型相反,将父类的对象作为子类对象来使用,那么我们联想继承的特性,就知道,这样做事有问题的,因为子类可以是父类的特例,子类可以有父类所没有的属性和行为.而这也是向下转型的弊端,当子类具有独特属性和行为时,使用向下转型就必然会导致他们的缺失.

   quadrilateral q = new square();  // 将子类对象赋值给父类类型对象.
    //  square s = q;  // 直接将父类对象转换为子类对象是不行的,就像数据的类型转换一样,
        square s = (square) q;  // 只能通过强制类型转换来向下转型

我们可以发现对象的类型转换,向上向下转型,和数据类型的转换有异曲同工之妙.向上转型就相当于低精度转向高精度,不会带来任何隐患和问题,向下转型就像低精度向高精度的转换,会有属性,行为的缺失.必须使用强制类型转换才行,否则报错.

  • 最后补充一点知识:
    我们可以通过instanceof关键字判断一个对象是否是某个类的实例化对象,其两个参数,object instenceof Exampleclass. 其返回值为boolean型.
System.out.println(s instanceof square);

更新时间:
2019-4-14
22:24

posted @ 2019-04-15 02:40  小舍先生  阅读(8651)  评论(0编辑  收藏  举报