一、继承
理解继承
Cat继承了Animal类,其中:Animal类称为父类/基类或超类,Cat可以称为Animal的 子类/派生类,继承之后,子类可以复用父类中成员,子类在实现时只需关心自己新增加的成员即可
Java中不支持多继承,仅支持A extends B 单继承//A extends B B extends C 多层继承 //A extends C B extends C 不同类继承自同一类。
public class TestExtend { public static void main(String[] args) { Dog d1 =new Dog(); d1.name = "xiaocs"; d1.age = 15; Cat c1 = new Cat(); c1.color = "red"; c1.type = "波斯"; c1.friendly(); }}/*** Dog未继承animal则无法调用animal中的成员变量和成员方法*/class Dog{ public int age; public String name; public void shot(){ System.out.println("汪汪汪"); }}//cat可以直接调用animal中的成员变量和成员方法class Cat extends animal{ public int weight; public String sex; public void eat(){ System.out.println("嘎嘎吃"); }}class animal{ public String color; public String type; public void friendly(){ System.out.println("对人类友好"); }}子类访问父类
子类和父类不存在同名成员变量
public class Base { int a; int b;}public class Derived extends Base{ int c; public void method(){ a = 10; // 访问从父类中继承下来的a b = 20; // 访问从父类中继承下来的b c = 30; // 访问子类自己的c }子类和父类成员变量同名
public class Base { int a; int b; int c;} public class Derived extends Base{ int a; // 与父类中成员a同名,且类型相同 char b; // 与父类中成员b同名,但类型不同 public void method(){ a = 100; b = 101; c = 102; // 子类没有c,访问的肯定是从父类继承下来的c // d = 103; // 编译失败,因为父类和子类都没有定义成员变量b }}成员变量访问遵循就近原则,自己有优先自己的,与父类同名也优先访问自己的,如果没有则向父类中找。
成员方法亦然,如果子类有则先访问子类的,子类没有先访问父类的,如果存在方法重载,则根据引用的情况,选择合适的方法
在子类方法中,如果想要明确访问父类中成员时,借助super关键字即可
二、super关键字
当父类和子类的成员变量或成员方法相同时,调用父类的成员变量或方法,使用super关键字
class Cat extends animal{ public int color; public String type; public void eat(){ //调用父类的成员变量 super.color = "red"; super.type = "波斯"; super.friendly(); System.out.println("嘎嘎吃"); }}class animal{ public String color; public String type; public void friendly(){ System.out.println("对人类友好"); }}子类的构造方法(无参数)若父类显式定义无参或者默认的构造方法,在子类构造方法第一行默认有隐含的super()调用,即调用基类构造方法public class TestExtend { public static void main(String[] args) { Cat c = new Cat(); }}class Cat extends animal{ public int size; public String name; public Cat(){ // super(); //注意子类构造方法中默认会调用基类的无参构造方法:super(), // 用户没有写时,编译器会自动添加,而且super()必须是子类构造方法中第一条语句, // 并且只能出现一次 System.out.println("Cat::"); } public void eat(){ System.out.println("嘎嘎吃"); }}class animal{ public String color; public String type; public animal() { System.out.println("animal::"); } public void friendly(){ System.out.println("对人类友好"); }}子类对象构造时,需要先调用父类构造方法,然后执行子类的构造方法。
子类的构造方法(有参数)
如果父类构造方法是带有参数的,此时需要用户为子类显式定义构造方法,并在子类构造方法中选择合适的父类构造方法调用,否则会编译失败
public class TestExtend { public static void main(String[] args) { Cat c = new Cat("red","波斯",45,"xiaos"); }}class Cat extends animal{ public int size; public String name; public Cat(String color, String type, int size, String name) { super(color, type); this.size = size; this.name = name; } public void eat(){ System.out.println("嘎嘎吃"); }}class animal{ public String color; public String type; public animal(String color, String type) { this.color = color; this.type = type; } public void friendly(){ System.out.println("对人类友好"); }}在子类构造方法中,super(...)调用父类构造时,必须是子类构造函数中第一条语句。
super(...)只能在子类构造方法中出现一次,并且不能和this同时出现
✅super和this之间的区别?
相同点:
1.都属于java 中的关键字
2.只能在类的非静态方法中使用,用来访问 非静态的方法和字段
3.在构造 方法中使用时必须是构造方法当中的第一条语句,并且二者不能同时存在
不同点:
1.this指的是当前对象的引用,super指的是当前对象对父类部分对象的使用
在非静态成员方法中,this用来访问本类的方法和属性,super用来访问父类继承下来的方法和属性
在构造方法当中,this用于调用本类的构造方法,super调用父类的构造方法,两种调用不能同时在构造方法中出现
构造方法中一定会存在super(...)的调用,用户没有写编译器也会增加,但是this(...)用户不写则没有
三、继承关系下的代码块
public class TestExtend { public static void main(String[] args) { Cat c = new Cat("red","波斯",45,"xiaos"); }}class Cat extends animal{ public int size; public String name; //5.子类的实例代码块 { System.out.println("cat::实例"); } //2.子类的静态代码块 static{ System.out.println("cat::static"); } //6.子类的构造方法 public Cat(String color, String type, int size, String name) { super(color, type); this.size = size; this.name = name; System.out.println("cat::构造"); } public void eat(){ System.out.println("嘎嘎吃"); }}class animal{ public String color; public String type; //3.父类的实例代码块 { System.out.println("animal::实例"); } //1。父类的静态代码块 static{ System.out.println("animal::static"); } //4.父类的构造方法 public animal(String color, String type) { this.color = color; this.type = type; System.out.println("animal::构造"); } public void friendly(){ System.out.println("对人类友好"); }根据执行结果可以的出以下结论:
父类的静态代码块>>子类的静态代码块>>父类的实例代码块>父类的构造方法>>子类的实例代码块>> 子类的构造方法
第二次实例化子类对象时,父类和子类的静态代码块都将不会再执行
四、protected关键字
访问限定:同一个包中的类和不同包中的子类
package TestDemo2;public class B { private int a; protected int b; public int c; int d;}在不同包中即package TestDemo 中
只有public和protected修饰的成员可以访问
五、final关键字
修饰变量时: 表示常量即不能修改
final int a = 10; a = 20; // 编译出错修饰类时: 表示此类不能被继承,即不能作为父类
//final修饰final class animal{ public String color; public String type; public animal(String color, String type) { this.color = color; this.type = type; System.out.println("animal::构造"); }}