- 继承
- 类的继承格式
- 代码演示:父子继承的基本关系
- 代码演示:继承中成员变量的访问
- 方法重写
- 代码演示:方法重写
- 重载和重写的区别
- 代码演示:重写与重载
- 父子类构造方法的访问
- super 使用的三种情况
- this 使用的三种情况
- 继承的三大特性
- java语言是单继承性[单根性]
- java语言是多继承性,即:继承有传递性
- 一个子类的直接父类是唯一的,但是一个父类可以有多个的子类
class 父类 {
}
class 子类 extends 父类 {
}
代码演示:父子继承的基本关系
package study.inherit;
// 父类(超类、基类)
public class Person {
String name;
int age;
private String id; // 父类中的身份证号权限私有化,进而无法访问私有的属性及特征,所以无法继承
public void eat() {
System.out.println("干饭!!!");
}
}
package study.inherit;
// 子类
public class Teacher extends Person {
public static void main(String[] args) {
// Teacher类中没有显示任何的成员变量及成员方法,但是可通过继承关系,就能够获得到“非私有”的成员属性及特征
Teacher teacher = new Teacher();
teacher.name = "yy";
teacher.age = 20;
teacher.eat();
System.out.println(teacher.name+",今年"+teacher.age+"!!!");
}
}
代码总结
1. 父类又称为超类、基类 2. 父类中私有的成员变量及方法,之所以子类无法访问私有的变量及方法,是因为无法被继承代码演示:继承中成员变量的访问
package study.inherit;
// 父类
public class FatherKind {
int fua = 10;
int b = 20;
public int getB(){
return b;
}
}
package study.inherit;
// 子类
public class ChildKind extends FatherKind {
int cha = 30;
int b = 40;
// public int getB(){
// return b;
// }
public void method(){
int a = 10; // 局部变量
System.out.println("子类的局部变量:"+a);
System.out.println("子类的成员变量:"+this.b); // 哪个对象调用当前的方法,那么this指代的就是那个对象[this可以是多个]
System.out.println("父类的成员变量:"+super.b); // 子类继承的是哪个父类,那么super指代的是那个父类的对象[super是唯一的]
}
}
package study.inherit;
// 测试类
public class KindTest {
public static void main(String[] args) {
System.out.println("====================通过对象调用各自的成员变量=====================");
FatherKind f = new FatherKind();
System.out.println("父类变量a:" + f.fua + " " +"父类变量b:" + f.b);
ChildKind c = new ChildKind();
System.out.println("子类变量a:" + c.cha + " " +"父类变量b:" + c.b);
System.out.println("通过子类访问父类的变量a:" + c.fua);
System.out.println("=============当父子类成员变量名相同,通过子类调用父类的变量==============");
// 问:父子类中,都有相同名称变量b,如何通过子类调用父类的b变量???可通过间接方式调用。getXxx()进行访问;
System.out.println("通过子类访问父类的变量b:" + c.getB()); // 前提条件:子类中没有getB()方法
// 答:父子继承关系,若子类中有getB()函数,优先在子类中进行调用;若子类中没有getB()函数,从父类中进行调用
// 说明:在继承关系中,对象能调用的成员变量、成员方法,优先在该对象本类中进行查找
System.out.println("=============查看当前对象的成员变量、父类的成员变量、局部变量==============");
c.method();
}
}
代码运行效果
====================通过对象调用各自的成员变量===================== 父类变量a:10 父类变量b:20 子类变量a:30 父类变量b:40 通过子类访问父类的变量a:10 ============当父子类成员变量名相同,通过子类调用父类的变量============== 通过子类访问父类的变量b:20 =============查看当前对象的成员变量、父类的成员变量、局部变量============== 子类的局部变量:10 子类的成员变量:40 父类的成员变量:20
代码总结
通过测试类,将父子类进行一定深度的探究 1. 通过父类的对象访问自己类中的成员变量。也通过子类的对象访问自己类中的成员变量 2. 父子类在继承关系中,子类访问父类的变量,但是父类不能访问子类变量 3. 在继承关系中,父子类成员变量中都存在相同的变量名,子类会优先访问本类的变量 4. 在继承关系中,父子类成员变量中都存在相同的变量名,子类一定要获取父类的变量,这时通过父类的getXxx(),间接访问。恰巧,子类也拥有getXxx(),子类会优先访问本类的方法 5. 通过当前的子类,来查看当前的子类成员、父类成员、局部变量方法重写
方法重写:当程序中父类的某一个方法并不能满足子类的需求时,子类可以重新定义该方法的内容与功能来满足子类的需求的一种操作。
重写注意事项 1. 方法名称相同,参数列表相同(签名相同) 2. 子类重写方法,前面是可以显示添加@Override,表示这个方法是重写的,也可以省略不写 3. 子类重写方法,父类的返回值类型是基本数据类型,子类的返回值也必须保持一致 父类的返回值类型是引用数据类型 a. 当父类的成员方法返回值类型是父类时,子类的重写方法的返回值类型可以是父类,也可以是子类 b. 当父类的成员方法返回值类型是子类时,子类的重写方法的返回值类型及返回值必须是子类 4. 修饰词:子类方法的修饰词权限必须大于或等于父类 【两种极端情况:1. 父类访问权限是public,子类访问权限也必须是public;2. 父类方法私有,子类无法重写(私有方法不能被继承)】 权限从小到大排序:public(公开)> protected(受保护)> 默认(default)> private(私有的) 注意:default是默认的,不用写,写了会报错代码演示:方法重写
(个人理解重写的修饰词:子类的权限 ≥ 父类的权限,重写是为了修改父子类的内容,所以调不调父类无所谓,子类必须可调 )
package study.inherit;
// 父类
public class Phone {
public void call(){
System.out.println("打电话");
}
public Phone show(){
System.out.println("显示电话号码");
return new NewPhone();
}
}
package study.inherit;
// 子类
public class NewPhone extends Phone {
@Override
public NewPhone show() {
super.show(); // 调用父类的方法
System.out.println("显示照片");
System.out.println("显示名字");
// return new NewPhone();
// 如果返回值是父类,那么子类的返回值可以是父类,也可以是子类
return new NewPhone();
}
}
package study.inherit;
// 测试类
public class PhoneTest {
public static void main(String[] args) {
// 父类Phone引用p,指向子类NewPhone的对象
// 例:动物 a = new 肉食动物();
Phone p = new NewPhone();
p.call();
p.show(); // 调用子类重写后的方法
}
}
重载和重写的区别
* 1.重写: Override (1)发生在有继蛋关系的父子类之间。 (2)方法名称和参数列表一定要保持一致 (3)返回值类型: 如果方法的返问值类型是: void 8种基本数据类型,返回值类型一定要保持一致! 如果方法的返回值类型是:引用数据类型,父类方法的返回的类型可以小于或者等于父类的返回的类型 (4)修饰词 子类方法的访问权限要 ≥ 父类访问权限。两种极端情况:【父类访问权限public:子类也一定public; 父类的访问权限private方法子类无法继承,就不可以重写】 ======重写遵循”运行期绑定” * 2.重载: Overload (1)发生在一个类中 (2)要发生重载,方法名一定要相同,参数列表一定要不用[个数的不同,类型的不用、顺序的不同] (3)对于返回值类型无要求。 (4)对于修饰词无要求 ======重载遵循”编译期绑定”代码演示:重写与重载
package study.inherit;
public class OverLoadAndOverride {
public static void main(String[] args) {
// 父类的引用指向子类的对象
Super obj = new Sub(); // sub 全称:subroutine 子程序、子代的意思
obj.f(); // 编译结果 sub.f()
System.out.println("===============================");
Goo goo = new Goo();
goo.g(obj); // 编译结果 g(Super)
// sub.f()
}
}
class Super {
public void f() {
System.out.println("super.f()");
}
}
class Sub extends Super {
public void f() {
System.out.println("sub.f()");
}
}
class Goo {
public void g(Super obj) {
System.out.println("g(Super)");
obj.f();
}
public void g(Sub obj) {
System.out.println("g(Sub)");
obj.f();
}
}
父子类构造方法的访问
在继承关系中,父子类的构造方法注意的事项 1. 子类构造方法,默认会调用父类的无参构造[super()] 2. 子类是通过关键字super对父类的构造方法进行调用 3. 一个构造方法中,super只能被调用一次,且必须位于构造子类方法的第一行 4. 父类中是有参构造,子类构造方法就不会隐式的提供super() (父类构造方法中携带参数列表,子类构造方法也必须携带参数列表)
代码演示:父子类构造方法的访问
package study.inherit;
public class ConstructionDemo {
public static void main(String[] args) {
Zi zi = new Zi();
}
}
class Fu{
public Fu() {
System.out.println("父类构造方法执行完毕!");
}
}
class Zi extends Fu{
public Zi() {
// 隐藏了父类构造方法super();
super(); // 此行写不写,依旧输出父类的无参构造
System.out.println("子类构造方法执行完毕!");
}
}
代码运行结果
父类构造方法执行完毕! 子类构造方法执行完毕!super 使用的三种情况
super关键字的三个作用 1. 在子类的成员方法中,访问父类的成员变量 2. 在子类的成员方法中,访问父类的成员方法 3. 在子类的构造方法中,访问父类的构造方法
代码演示:super 使用的三种情况
package study.inherit;
public class SuperDemo {
public static void main(String[] args) {
Zi zi = new Zi();
zi.method1();
zi.method2();
}
}
// 父类
class Fu{
int num = 10;
public Fu() {
System.out.println("这是父类的构造方法!!!");
}
public void method() {
System.out.println("父类的成员方法!!!");
}
}
// 子类
class Zi extends Fu{
public void method1() {
System.out.println("访问父类的成员变量:"+super.num); // 访问父类的成员变量
}
public void method2() {
super.method(); // 访问父类的成员方法
}
public Zi() {
super(); // 调用父类的方法构造
}
}
代码运行效果
这是父类的构造方法!!! 访问父类成员变量:10 父类的成员方法!!!this 使用的三种情况
this关键字的三个作用 1. 在子类的成员方法中,访问本类的成员变量 2. 在子类的成员方法中,访问本类的其他成员方法 3. 在子类的构造方法中,访问本类的其他构造方法【多个构造方法出现,要不明构造间的死循环】 注意:构造方法是不可以自己调用自己
代码演示:this 使用的三种情况
package study.inherit.demo2;
public class ThisDemo {
public static void main(String[] args) {
Zi zi = new Zi();
zi.showMsg();
zi.method1();
}
}
class Fu{
int num = 1;
}
class Zi extends Fu{
// 成员变量
int num = 3;
// 构造方法
public Zi() {
// this(1,2); 如果显示此话,出现构造方法死循环
System.out.println("这里是无参构造!!!");
}
public Zi(int num) {
this();
System.out.println("这里是有一参构造!!!");
}
public Zi(int num1,int num2) {
this(12);
System.out.println("这里是有两参构造!!!");
}
//成员方法
public void showMsg() {
System.out.println(this.num); // 调用成员变量
}
public void method1() {
this.method2(); // 调用其他成员方法
System.out.println("子类方法1已经执行!!!");
}
public void method2() {
System.out.println("子类方法2已经执行!!!");
}
}
代码运行效果
这里是无参构造!!! 3 子类方法2已经执行!!! 子类方法1已经执行!!!继承的三大特性 java语言是单继承性[单根性]
一个类的直接父类只能有一个
class A{ }
class B extends A{ } // 正确
class C{}
class D extends A, C{ } // 惜误
java语言是多继承性,即:继承有传递性
儿子可以有爸爸,爸爸也可以有爸爸
class A{}
class B extends A{} // 正确
class C extends B{} // 正确
那么可以推导出: C也维承了A
一个子类的直接父类是唯一的,但是一个父类可以有多个的子类class A{}
class B extends A{} // 正确
class C extends A{} // 正确
B与C是并列关系



