Java核心(接口、继承和多态-继承2)

一、Object 类

    在开始学习使用 class 关键字定义类时,就应用到了继承原理,因为在 Java 中,所有的类都直接或间接继承了 java.lang.Object 类。 Object 类是比较特殊的类,它是所有类的父类,是Java 类层中的最高层类。当创建一个类时,总是在继承,除非某个类已经指定要从其他类继承,否则它就是从 java.lang.Object 类继承而来的,可见 Java 中的每个类都源于 java.lang.Object 类,如 String 、 Integer 等类都是继承于 Object 类;除此之外自定义的类也都继承与 Object 类。由于所有类都是 Object 子类,所以在定义类时,省略了 extends Object 关键字。

    在 Object 类中主要包括 clone() 、 finalize() 、 toString() 等方法,其中常用的两个方法为 equals() 和 toStirng() 方法。由于所有的类都是 Object 类的子类,所以任何类都可以重写 Object 类中的方法。

    在 Object 类中的 getClass() 、 notify() 、 notifyAll() 、 wait() 等方法不能被重写,因为这些类被定义为 final 类型。

    1.1  getClass() 方法

    getClass() 方法时 Object 类定义的方法,它会返回对象执行时的 Class  实例,然后使用此实例调用 getName() 方法可以取得类的名称。

    语法如下 :

getClass().getName();

    可以将 getClass() 方法与 toStirng() 方法联合使用。

    1.2  toString() 方法

    toStirng() 方法的功能是将一个对象返回为字符串形式,它会返回一个 String 实例。在实际的应用中通常重写 toString() 方法,为对象提供一个特定的输出模式。当这个类转换为字符串或字符串连接时,将自动调用重写的 toString() 方法。

    eg : 创建类,在类中重写 Object 类的 toString() 方法,并在主方法中输出该类的实例对象。

public class ObjectInstance{
    public String toString(){        //重写 toString() 方法
        return "在" + getClass().getName() + "类中重写 toString() 方法"; 
    }
    public static void main(String[] args){
        System.out.println(new ObjectInstance)); //打印本类对象
    }
}

    运行结果为 :

在 ObjectInstance 类中重写 toString() 方法

    在本实例中重写父类 Object 的 toString() 方法,在子类的 toString() 方法中使用 Object 类中的 getClaa() 方法获取当前运行的类名,定义一段输出字符串,当用户打印 ObjectInstance 类对象时,将自动调用 toString() 方法。

    1.3  equals()  方法

    " == " 运算符比较的是两个对象的引用是否相等,而 equals() 方法比较的是两个对象的实际内容。

    eg : 创建类,在类的主方法中定义两个字符串对象,调用 equals() 方法判断两个字符串对象是否相等。

class V{ //自定义类
}
public class OverWriteEquals{
    public static void main(String[] args){
        String s1 = "123";//实例化两个对象 ,内容相同
        String s2 = "123";
        System.out.println(s1.equals(s2));
        V v1 = new V();//实例化两个 V类对象
        V v2 = new V();
        System.out.println(v1.equals(v2));
    }
}

    运行结果为 :

true
false

    从本例中的结果中可以看出,在自定义的类中使用 equals() 方法进行比较时,将返回 false ,因为 equals() 方法的默认实现是使用 " == " 运算符比较两个对象的引用地址,而不是比较对象的内容,所以要想真正做到比较两个对象的内容,需要在自定义类中重写 equals() 方法。

二、对象类型的转换

    对象类型转换的转换在 Java 编程中经常遇到,主要包括向上转型与向下转型操作。

    2.1  向上转型

    因为平行四边形是特殊的四边形,也就是说平行四边形是四边形的一种,那么就可以将平行四边形对象看作是一个四边形对象。例如,鸡是家禽的一种,而家禽是动物中的一类,那么也可以将鸡看作是一个动物对象。

    eg :创建两个类,是第一类继承第二个类,然后再主方法中太哦用父类的 draw() 方法。

class Quadrangle{        //四边形类
    public static void draw(Quadrangle d){        //四边形类中的方法
        //SomeSentence
    }
}
public class Parallelogram extends Quadrangle{        //平行四边形类,继承了四边形类
    public static void main(String[] args){
        Parallelogram p = new Parallelogram();        //实例化平行四边形类对象引用
        draw(p);        //调用父类方法
    }
}

    平行四边形类继承了四边形类,四边形类存在一个 draw() 方法,它的参数是 Quadrangle 类型,而在平行四边形类的主方法中调用 draw() 时给予的参数类型却是 Parallelogram 类型的。就是平行四边形也是一种类型的四边形,所以可以将平行四边形类的对象看作是一个四边形类的对象,这就相当于 " Quadrangle obj = new Parallelogram " ,就是把子类对象赋值给父类类型的变量,这种技术被称为“ 向上转型 ”。试想一下正方形类的 draw() 方法中根据不同的图形对象设置不同的处理,就可以做到在父类中定义一个方法完成各个子类的功能,这样可以使同一份代码毫无差别地运用到不同类型上,这就是多态机制的基本思想。

    2.2  向下转型

    通过向上转型可以推理出向下转型是将较抽象类转换为较具体的类。这样的转型通常会出现问题,例如,不然能说四边形是平行四边形的一种、所有的鸟都是鸽子,因为这非常不合乎逻辑。可以说子类对象总是父类的一个实例,但父类对象不一定是子类的实例。

    eg : 修改上个例子,在 Parallelogram 类的主方法中将父类 Quadrangle 的对象赋值给子类 Parallelogram 的对象的引用变量将使程序产生错误。

class Quadrangle{
    public static void draw(Quadrangle q){
        //SomeSentence
    }
}
public class Parallelogram ectends Quadrangle{
    public static void main(Stirng[] args){
        draw(new Parallelogram());
        // 将平行四边形类对象看作是四边形对象,称为向上转型操作
        Quadrangle q = new Parallelogram();
        // Parallelogram p = q ;
        // 将父类对象赋予子类对象,这种写法是错误的。
        // 将父类对象赋予子类对象,并强制转换为子类型,这种写法是正确的。
        Parallelogram p = (Parallelogram) q;
    }
}

    可以看出,如果将父类对象直接赋予子类,会发生编译器错误,因为父类对象不一定是子类的实例。例如,一个四边形不一定就是指平行四边形,它也许是平行四边形,它也许是梯形,也许是正方形,也许是其他带有四条边的不规则图形。

    越是具体的对象具有的特性越多,越抽象的对象具有的特性越少。在做向下转型操作时,将特性范围小的对象转换为特性范围大的对象肯定会出现问题,是有意这时需要告知编辑器这个四边形就是平行四边形。将父类对象强制转换为某个子类对象,这种方式成为显式类型转换。

    当在程序中使用向下转型技术时,必须使用显式类型转换,向编辑器指明将父类转换为哪一种类型的子类对象。


  



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值