Java的第二大特性-----》继承
一、什么是继承
继承就是有一个类与另一个类的关系,也可以说一个类拥有另一个类的开放的属性和方法。举例说明就是,儿子继承父亲的资产,那么他便可以享用父亲提供给他的便利。继承中可以体现出来的是代码的复用,子类可以直接用父类定义的属性和方法。注意:java中是单继承 . 使用的方式是extends关键字
如下:
public class Dog extends Animal{ }
public class Initial { public static void main(String [] args){ Dog dog=new Dog(); } }
这便是一个继承,动物类是父类,Dog类是子类,继承了动物类,并且在Dog类中没有任何的代码语句,可以在主类中new 一个Dog对象出来,就是继承的好处所在了。
那么,问题来了。。。。
如果子类需要的方法父类提供不了怎么办?
那就是方法的重写
二、继承之方法的重写
a. 当子类所需要的父类给予不了,那么子类必须自力更生,自己实现父类的方法,当然这里也有就近原则,重写后的方法会被优先调用。没有规矩,不成方圆
重写的规则:重写的方法返回值类型、方法名、参数都要相同
b.举例说明方法的重写
Object是所有类的父类,想当于鼻祖之类的,如果有类没有使用extends关键字,那么默认的继承的Object.
Object中有两个方法比较有名,toString方法和equals方法
i).Object 中的 toString()方法输出的是哈希码值(对象地址字符串),用来唯一区分对象相当于人的身份证号,利用哈希算法生成的,前部分是包名,后部分是对象在内存的地址,然后我们平时输出最多的字符串就是转换成字符串,那么我们可以重写toString
ii).Object 中的equals方法是比较的两个引用是否指向同一块内存区域,Dog dog =new Dog()中的 dog 其实是一个引用,并不是一个被创建的对象,这里只是把对象的引用赋给了变量dog,但是我们平时进行的比较都是比较的两个对象的值是否一样,不会i去比较是否指向了同一块区域,所以我们需要重写equals方法
public class Initial{ public static void main(String [] args){ Dog dog=new Dog(); Dog dog2=new Dog(); if(dog.equals(dog2)){ System.out.println("两个对象是相同的"); }else{ System.out.println("两个对象是不相同的"); }
这里new 了两次意思就是创建了两个地址空间,那么肯定是不同的
这里重写了equals方法,进行判断两个对象的值是否相同
@Override public boolean equals(Object obj) { if(this==obj) return true; if(obj==null) return false; if(obj.getClass()==obj) return true; Dog other=(Dog)obj; if(other.age!=((Dog) obj).age) return false; return true; }
当然了,方法的重写是按需要的,所有的重写的方法都不一定是一样的。
三、继承的初始化顺序
父类有构造方法、属性,子类也有构造方法和属性,那么到底他们是怎么样的初始化顺序的呢?
从上面的例子可以看出来,当new 一个Dog的时候,会先执行父类的构造方法,再执行子类的构造方法;而构造方法和属性的初始化却是先执行的属性的初始化,再执行构造方法的初始化(先执行的被覆盖了,结果中便是后执行的)。所以他们的初始化的顺序是:
父类的属性初始化-----》父类的构造方法初始化--------》子类的属性初始化---------》子类的构造方法初始化
四、继承之final关键字
final 关键字可以修饰类、方法、属性、变量
a.当final 修饰类时表示这个类不能被继承
b.当final 修饰方法时表示这个方法不能被重写(覆盖)
c.当final 修饰属性时,在声明的时候和构造方法中须有一处对其进行初始化,不然的话编译器会报错(编译器会对普通的属性或者变量进行隐式初始化)。
d.当final 修饰变量时,则为常量,后面不可修改。
final表示的就是最终的,最后的
五、继承之super关键字
super在子类的内部使用,代表的是父类对象,那么可以使用super 获取父类的属性和方法,分别为:super.属性和super.方法
注意:super 关键字与其构造方法有一定的关系
a.如果父类的构造方法是无参的构造方法,子类的构造方法中隐式调用了super(),当然也可以显示调用,并且在构造方法的第一行
b.如果在父类中的构造方法是自定义的有参的构造方法,那么在子类中必须显式的调用有参的构造方法,如下图
c.如果子类构造方法中既没有显式的调用父类的构造方法,父类中也没有无参的构造方法,那么编译器会报错。
以上便是总结的java的继承这一大特性。