1.继承
1-1:什么是继承?
继承是面向对象三大特征之一,也是实现软件复用的重要手段,java的继承具有单继承的特点,每个子类只有一个直接父类
2.如何实现继承?
2-1:关键词 extends
在java中使用extends作为继承的关键字,extends在英文中意思是拓展,实际上,拓展其实更加容易理解(子类作为父类的拓展),子类是一种特殊的父类,拓展了父类的功能
举个栗子:
public class Bird {
public void fly(){
System.out.println("i am flying in the sky");
}
}
public class Ostrich extends Bird {
/**
在内部写逻辑 继承Bird
*/
}
2-2:java继承的特征:单继承
什么叫单继承呢?一个很形象的栗子:九代单传 ,同时,如果定义一个java类时,没有定义它的父类,则该类默认去拓展java.lang.Object 因此,Object类是所有类的父类,要么是直接父类,要么是间接父类。
3.继承了父类之后呢?
3-1:方法的重写
大部分时候,子类总是以父类为基础,额外增加新的成员变量和方法,但是,为了更好的实现代码复用,子类需要去重写父类的方法,例如:鸟类都包含了飞翔,但是鸵鸟也是一种特殊的鸟,奈何不会飞,所以需要重写飞翔的方法
举个栗子:
public class Bird {
public void fly(){
System.out.println("i am flying in the sky");
}
}
public class Ostrich extends Bird {
/**
* 方法重写:函数名一致 内部处理逻辑不通
*/
public void fly(){
System.out.println("i am only running in the land");
}
public static void main(String[]args){
// Bird bird=new Ostrich();
Ostrich os=new Ostrich();
os.fly();
}
}
方法重写需要注意:
方法名,形参列表相同(两同),子类对象的返回值类型比父类返回值类型更小或相等,子类方法声明抛出的异常类比父类方法声明抛出的异常类更小或相等(两小);子类方法的访问权限比父类方法的访问权限更大或相等(一大)
同时:重写方法和重写方法之间要不是类方法,要不是实例方法,不能一个是类方法,一个是实例方法,否则会编译错误
3-2:方法重载和重写的区别?
说实话 虽然长的很像,但是把两者比起来本身没有太大的意义,重载发生在同一个类的多个同名方法中,重写发生在子类和父类的同名方法中,父类和子类之间也可以进行重载
4.super关键字
如果要在子类的方法中调用父类被覆盖的实例方法,可以使用super关键字来调用父类被覆盖的实例方法,所以在子类中 既可以使用重写后的方法,也可以使用父类中的方法
举个栗子:
//Bird类和上述一致
public class Ostrich extends Bird {
/**
* 方法重写:函数名一致 内部处理逻辑不通
*/
public void fly(){
System.out.println("i am only running in the land");
}
public void callOverridedMethod(){
super.fly();
}
public static void main(String[]args){
// Bird bird=new Ostrich();
Ostrich os=new Ostrich();
os.fly();
//调用父类的fly方法
os.callOverridedMethod();
}
}
super不能出现在static修饰的方法中,static的修饰方法是属于类的 ,如果使用super的话 就失去了意义(参考this和static不能一起用的栗子)
5.子类如何调用父类的构造器?
子类无法获得父类的构造器,但是子类可以调用父类的构造器的初始化代码,类似于提到的一个构造器调用另一个的构造器(this方法)
举个栗子:
public class Creature {
public Creature(){
System.out.println("Creature 无参数的构造器");
}
}
public class Animal extends Creature {
public Animal(String name){
System.out.println("Animal 一个带参数的构造器,"+"该动物的name为"+name);
}
public Animal(String name,int age){
this(name);
System.out.println("Animal 两个带参数的构造器,"+"该动物的age为"+age);
}
}
public class pig extends Animal {
public pig(){
//调用父类构造器
super("佩奇",3);
System.out.println("调用本身无参构造器 但是调用了父类构造器");
}
public static void main(String[]args){
new pig();
}
}
观察一下结果:
所以,创建任何对象,总是从该类所在的继承树的顶端构造器开始执行,然后依次向下执行。最后才执行本类的构造器,如果某个父类通过this调用了同类中重载的构造器,会依次执行父类中的多个构造器