Java--继承
1.程序中的继承,是类与类之间特征(属性)和行为(方法)的一种赠与或获得
两个类之间的继承关系,必须满足“Is a”的关系
2.功能越精细,重合点越多,越接近直接父类
功能越粗略,重合点越少,越接近直接Object类。(万物皆对象)
3.在一组相同或类似的类中,抽取出共享的特征和行为,定义在父类中,实现重用。
4.继承语法:class 子类 extends 父类(){}//定义子类时,显示继承父类
应用:产生继承关系之后,子类可以使用父类中的属性和方法,也可以定义子类中独有的属性和方法
好处:既提高代码的重复性,又提高代码的可扩展性
继承的实例如下:狗狗类继承动物类
package com.monv.inherit_01; /** * 动物类--父类 * @author Monv * */ public class Animal { //品种 String breed; //年龄 int age; //性别 String Sex; //吃 public void eat() { System.out.println("吃......"); } //睡 public void sleep() { System.out.println("睡......"); } } package com.monv.inherit_01; /** * 狗狗类 * @author Monv * */ public class Dog extends Animal{ //毛色--狗狗类定义的属性 String furColor; //跑--狗狗类定义的方法 public void run() { System.out.println("跑......"); } } --------------------------测试--------------------------------- package com.monv.inherit_01; public class TestDog { public static void main(String[] args) { //创建一个wangcai动物类实例 Dog wangcai = new Dog(); wangcai.breed="萨摩";//父类的属性 wangcai.age = 2;//父类的属性 wangcai.Sex ="公";//父类的属性 wangcai.furColor = "白色";//子类的属性 wangcai.eat();//父类的方法 wangcai.sleep();//父类的方法 wangcai.run();//子类的方法 } } 结果: 吃...... 睡...... 跑...... ----------------------------------------------------------------------
5.继承的特点:Java为单继承,一个类只能有一个直接父类,但可以多级继承,属性和方法逐级叠加。
6.不可继承
a.构造方法:类中的构造方法,只负责创建本类对象,不可继承
b.private(私有的)修饰的属性和方法(仅本类可见)
c.父子类不在同一个package(包)中时,default(默认修饰符,不用写)修饰的属性和方法,仅同包可见
本类 | 同包 | 非同包子类 | 其他 | |
private(私有的) | 可见 | 不可见 | 不可见 | 不可见 |
default(默认) | 可见 | 可见 | 不可见 | 不可见 |
protected(保护的) | 可见 | 可见 | 可见 | 不可见 |
public(共开的) | 可见 | 可见 | 可见 | 可见 |
7.方法的重写/覆盖
当父类提供的方法无法满足子类需求时,可在子类中定义和父类相同的方法进行重写(Override);
方法重写的原则:
7.1 方法名称、参数列表、返回值类型必须与父类相同
7.2 访问修饰符可与父类相同或是比父类更宽泛
方法重写的执行:
子类重写父类方法后,调用时优先执行子类重写后的方法。
eg:在狗狗类中对父类中eat的方法进行重写
package com.monv.inherit_01; /** * 狗狗类 * @author Monv * */ public class Dog extends Animal{ //毛色--狗狗类定义的属性 String furColor; @Override//对父类eat()方法进行重写 public void eat() { System.out.println(breed+"正在吃狗粮!"); } //跑--狗狗类定义的方法 public void run() { System.out.println("跑......"); } } -------------------------测试----------------------------------- package com.monv.inherit_01; public class TestDog { public static void main(String[] args) { //创建一个wangcai动物类实例 Dog wangcai = new Dog(); wangcai.breed="萨摩";//父类的属性 wangcai.age = 2;//父类的属性 wangcai.Sex ="公";//父类的属性 wangcai.furColor = "白色";//子类的属性 wangcai.eat();//子类中的方法(重写了父类eat的方法) wangcai.sleep();//父类的方法 wangcai.run();//子类的方法 } } 结果: 萨摩正在吃狗粮! 睡...... 跑...... ------------------------------------------------------------
8.super关键字
在子类中,可以直接访问从父类继承到的属性和方法,但如果父子类的属性或方法存在重名(属性遮蔽、方法重写)时,需要加以区分,才可以专项访问。
如果想要访问父类同名的方法,则需要加 super关键字来访问,super.方法名/属性;
package com.monv.inherit_02; public class Father { int value = 100; public void show() { System.out.println("父类的show方法"); } }
package com.monv.inherit_02; public class Son extends Father { int value = 200; @Override//重写父类的show方法 public void show() { super.show();//如果想要调用父类的show方法 用super.方法名 调用 System.out.println("子类的show方法"); } public void print() { int value = 300; System.out.println(value);//局部变量 结果300 System.out.println(this.value);//本类实例变量 结果 200 System.out.println(super.value);//父类实例变量 结果 100 } } --------------------------------测试------------------------------------- package com.monv.inherit_02; public class TestSon { public static void main(String[] args) { Son son = new Son(); son.show();//调用的是Son类中的show方法 son.print(); } } 结果: 父类的show方法 子类的show方法 300 200 100 -------------------------------------------------------------------------
9.继承中的对象创建
在具有继承关系的对象创建中,构建子类对象会先构建父类对象;由父类的共性内容,叠加子类的独有内容,组合成完整的子类对象。
10.继承后的对象构建过程(构建子类对象时,先构建父类对象)
public class TestSuper{ public static void main(String[] args){ new C(); } } class A{}; class B extends A{}; class C extends B{};
package com.monv.inherit; public class A { int num1; int num2; public void m1(){ System.out.println("A类的m1()方法"); } public A(){ System.out.println("A的默认构造方法"); } } package com.monv.inherit; public class B extends A{ int num3; int num4; public void m2(){ System.out.println("B类的m2()方法"); } public B (){ System.out.println("B的默认构造方法"); } } -----------------------------测试-------------------------------------- package com.monv.inherit; public class TestB { public static void main(String[] args) { B bb = new B(); bb.m1(); bb.m2(); } } 结果: A的默认构造方法 B的默认构造方法 A类的m1()方法 B类的m2()方法 ------------------------------------------------------------------------- 说明:对象bb在实例化的时候 会先构建B的父类A 所以会先执行A类中默认构造方法中的代码,然后再执行B类默认构造方法中的代码
11.super调用父类构造
super():表示调用父类无参构造方法。如果没有显示书写,隐式存在于子类构造方法的首行。
super(实参):表示调用父类有参构造方法。
package com.monv.inherit; public class A { int num1; int num2; public void m1(){ System.out.println("A类的m1()方法"); } public A(){ System.out.println("A的默认构造方法"); } public A(int num1,int num2){ System.out.println("A类的带参构造"); this.num1 = num1; this.num2 = num2; } } ------------------------------------------------------------- package com.monv.inherit; public class B extends A{ int num3; public void m2(){ System.out.println("B类的m2()方法"); } public B (){ super();//这个语句 可写可不写(不写会默认添加) 调用A类的默认构造方法 System.out.println("B的默认构造方法"); } public B(int num1,int num2,int num3){ // super();//带参构造中也会默认调用A的无参构造 super(num1, num2);//调用父类的带参构造方法 给num1和num2 赋值 System.out.println("B类的带参构造"); // this.num1 = num1; // this.num2 = num2; this.num3 = num3; } } -------------------------------测试------------------------------------ package com.monv.inherit; /** * super 调用父类的构造方法 * 1.super调用父类的无参构造 * 2.super调用父类的带参构造 * @author Administrator * */ public class TestB { public static void main(String[] args) { B bb = new B(111,222,333); bb.m1(); bb.m2(); } } 结果: A类的带参构造 B类的带参构造 A类的m1()方法 B类的m2()方法 ---------------------------------------------------------------------
12.this和super
this:表示当前对象引用,调用本类(包括继承)的属性、方法、本类构造方法
super:表示父类对象引用,调用父类的属性、方法、构造方法
this或super使用在构造方法中时,都要求在首行。当子类构造中使用了this()或this(实参),即不可在同时书写super()或super(实参),会由this()指向的构造方法完成super()的调用。
13.总结:
super关键字的第一种用法:在子类的方法中使用“super.”的形式访问父类的属性(super.父类属性)和方法(super.父类方法)
super关键字的第二种用法:在子类的构造方法的首行,使用super()或super(实参),调用父类的构造方法。
注意:如果子类构造方法中,没有显示定义super()或super(实参),则默认提供super()。
同一个子类构造方法中,super()和this()不可同时存在。