1.什么是继承
子类继承父类就是对父类的扩展,继承时会自动拥有父类所拥有的处private之外的所有成员
作用:增加代码复用
语法格式:
class 子类名 extends 父类名{
…………
}第9章 Java类的三大特性之一:继承
例子:
1 //测试类,创建子类对象,可以直接调用属性和方法 2 public class testDog { 3 public static void main(String[] args) { 4 Dog dog = new Dog(); 5 dog.age=10; 6 dog.name="旺财"; 7 dog.eat(); 8 } 9 } 10 11 //子类,没有写任何方法 12 public class Dog extends Animal { 13 14 } 15 16 //测试类,创建子类对象,可以直接调用属性和方法 17 public class testDog { 18 public static void main(String[] args) { 19 Dog dog = new Dog(); 20 dog.age=10; 21 dog.name="旺财"; 22 dog.eat(); 23 } 24 } 25 26 27 ………………………… 28 动物具有吃东西的能力
2.继承中的方法的重写
子类在继承父类之后,可以把这个方法重写,并优先调用子类的方法,就近原则。
方法重写是在继承时候对父类中存在的方法重新定义,重载是指一个类中有几个方法的名字是不一样的,只有在接收不同的参数时,才会调用对应的那个方法
继承时方法的重写有一些限制:
1.返回值类型
2.方法名
3.参数类型及个数
上面三个都要与父类继承的方法相同,如此才叫方法的重写
例子:
1 //父类 2 public class Animal { 3 public String name; 4 public void eat(){ 5 System.out.println("动物"+name+"是可以吃东西的"); 6 } 7 } 8 9 //子类,重写了eat()方法 10 public class Dog extends Animal { 11 12 public void eat() { 13 System.out.println("这里是在子类中重写的方法"); 14 } 15 } 16 17 18 //测试类,创建子类对象,可以直接调用属性和方法 19 public class testDog { 20 public static void main(String[] args) { 21 Dog dog = new Dog(); 22 dog.name="旺财"; 23 dog.eat(); 24 } 25 } 26 27 ……………… 28 这里是在子类中重写的方法
3.继承初始化顺序
继承的初始化顺序:
1.使用类的时候都是在创建对象的时候,在创建子类对象时,是先初始化子类还是先初始化父类呢?
答案是先初始化父类再初始化子类
这个可以通过分别在父类和子类构造函数中打印语句,肯定是父类先打印出来
2.既然是先初始化父类再初始化子类,那么是先初始化属性还是先初始化构造方法呢?
答案是先初始化属性,再初始化构造方法
总结:创建一个子类对象时,先初始化父类的属性,然后初始化父类构造方法;再初始化子类属性,然后子类构造方法
4.父类中final的使用
final关键字:
使用final关键字做标识有“最终的”含义
final可以修饰类,方法,属性,变量
若修饰类:则该类不允许被继承
若修饰方法:则该方法不允许被重写(覆盖)
若修饰属性:则该类的属性不会进行隐式的初始化(类的初始化属性必须有值),或在构造方法中赋值(但只能选其一)
若修饰变量:则该变量的值只能在定义的时候赋值,即变为常量
5.子类中super的使用
super关键字:
在对象的内部使用,可以代表父类对象
1.访问父类的属性
super.age
2.访问父类的方法
super.eat()
注意:
父类对象的属性和子类对象的属性并无关系,是两个属性
super与构造方法之间的关系:
1.子类的构造过程当中必须调用父类的构造方法
举个例子:创建子类对象的时候,父类的构造方法也会执行,相当与在子类的构造方法中隐式的写了一个super
1 //父类 2 public class Animal { 3 public Animal(){ 4 System.out.println("父类执行了"); 5 } 6 7 } 8 9 //子类 10 public class Dog extends Animal { 11 public Dog(){ 12 //子类构造方法,此处隐式写了一个super 13 System.out.println("子类执行了"); 14 } 15 16 } 17 18 //测试类,创建子类对象 19 public class testDog { 20 public static void main(String[] args) { 21 Dog dog = new Dog();//创建子类对象 22 23 } 24 } 25 26 ……………… 27 父类执行了 28 子类执行了
2.如果子类的构造方法中没有显示调用父类的构造方法,则系统默认调用父类无参的构造方法。
3.如果显示的调用构造方法,必须在子类的构造方法的第一行,显示调用用super();
4.如果子类构造方法中记没有显示调用父类的构造方法,而父类又没有无参的构造方法,则编译出错。
解释:父类默认是有无参构造方法的,如果自己定义了一个有参的构造方法,则不会再自动添加无参构造方法。而子类构造方法中,如果没有super(),则默认只会调用父类的无参构造方法,如果要调用父类的有参构造方法,则只需要在super(参数);
例子:
1 //父类 2 public class Animal { 3 public int age; 4 public Animal(int age){ 5 this.age=age; 6 System.out.println("父类执行了"+this.age); 7 } 8 9 } 10 11 //子类 12 public class Dog extends Animal { 13 public Dog(){ 14 super(10); 15 System.out.println("子类执行了"); 16 } 17 18 } 19 20 //测试类,创建子类对象 21 public class testDog { 22 public static void main(String[] args) { 23 Dog dog = new Dog(); 24 25 } 26 }
总结一下,其实上面说了这么多就一个意思:
如果父类有无参构造方法,super()写不写没关系,如果没有无参构造方法,则需要写super(),并用super()传递参数
6.Java的Object类
1.Object类是所有类的父类,如果一个类没有使用extends,关键字明确标识继承另外一个类,那么这个类默认继承Object
2.Object类中的方法,适合所有子类
3.Object类中的几种方法:
toString()方法:
Object类里面定义的toString方法是返回对象的哈希码(对象地址字符串)
如果直接输出对象名,就会执行toStirng()方法,例如:
System.out.println(实例化对象名)
可以通过在子类中重写toString()方法输出对象的属性
public String toString(){ return "Dog[age"+age+"]"; }
equals()方法
源码中比较的是对象的引用是否指向统一块内存地址,
子类中可以修改为比较两个对象的值是否相等。可以这样修改:
1 //父类 2 public class Animal { 3 public int age; 4 5 6 } 7 8 //子类 9 public class Dog extends Animal { 10 @Override 11 public boolean equals(Object obj) { 12 if (this==obj) //判断引用的地址是否相同 13 return true; 14 if (obj==null) //判断比较的值是不是空值 15 return false; 16 if (getClass()!=obj.getClass()) //比较两个对象类的的代码信息 17 return false; 18 Dog other = (Dog) obj; 19 if (age != other.age) //判断两个对象的属性值是否相等 20 return false; 21 return true; 22 } 23 } 24 25 26 //测试类,创建子类对象 27 public class testDog { 28 public static void main(String[] args) { 29 Dog dog = new Dog(); 30 Dog dog2 = new Dog(); 31 if(dog.equals(dog2)){ 32 System.out.println("两个对象是相同的"); 33 }else{ 34 System.out.println("两个对象是不相同的"); 35 } 36 37 } 38 }