文章目录
关于Java继承方面的基础知识汇总
首先要知道Java的三大特征:封装性,继承性,多态性。
而继承就是多态的前提,如何没有继承,就没有多态。
学好继承是重中之重!!!
1.父类与子类
父类又名超类,基类。子类又名派生类。
而父类与子类之间的关系特点为:
(1).子类可以拥有并使用父类的全部内容。
(2).子类还可以拥有并使用自己的内容。
2.继承的格式
权限修饰符 class 父类名称{
//****
}
权限修饰符 class 子类名称 extends 父类名称{
//****
}
3.继承的使用
3.1成员方法的调用
首先,我们尝试创建父类和子类
//父类
class Employee {
public void method1() {
System.out.println("父类方法执行");
}
}
//子类,事实上子类已经包含有父类的方法
class Teacher extends Employee {
public void method2() {
System.out.println("子类方法执行");
}
//在main方法中
Teacher one = new Teacher();
one.method1();//输出:父类方法执行
one.method2();//输出:子类方法执行
事实上,一个父类可以被多个子类所继承,但一个子类只能继承一个父类!!!
//如,接着上面的代码,再次创建一个类
class Worker extends Employee {
}//正确
class Worker extends Employee,Teacher {
}//错误
Worker one1=new Worker();
one1.method1();//正常输出
3.2成员变量的使用
首先,构造类
class Employee {
int num2 = 30;
}
class Teacher extends Employee {
int num1=20;
}
接下来输出
Teacher one = new Teacher();//必须创建子类对象
System.out.println(one.num1);//20
System.out.println(one.num2);//30
【注意】:
(1).明确调用方法
类名 对象名=new 类名();//创建对象
对象名.调用方法/变量名;//通过对象调用
(2).只有创建子类对象才能使用子类自己和相关父类的内容,但是如果创建父类对象仅仅能使用父类自己的内容,并不能使用子类内容!!
3.3重名成员变量和重名成员方法的使用
1.重名成员变量的使用
(1).直接寻找法
使用规则是:优先输出所创建对象的类中的变量,如果没有,则向该类的父类寻找。
//首先,构造类,使两个类的成员变量重名
class Employee {
int num = 30;
}
class Teacher extends Employee {
int num=20;
}
//接下来输出
Teacher one = new Teacher();//必须创建子类对象
System.out.println(one.num);//输出结果为20
解释:你创建的对象one所属的类是Teacher,则优先在该类寻找变量,如果没有,则向父类寻找,如果父类没有,则编译报错。
(2).间接寻找法
使用规则是:通过成员方法访问成员变量
class Employee {
int num = 30;
public void method(){
System.out.println(num);
}
}
class Teacher extends Employee {
int num=20;
public void method2(){
System.out.println(num);
}
}
Teacher one = new Teacher();
one.method();//30
解释:通过one对象调用method方法,该方法属于父类,就执行父类方法。
2.重名成员方法的使用
使用规则是:优先调用所创建对象的类中的方法,如果没有,则向该类的父类寻找。
//参考代码
class Employee {
public void method() {
System.out.println("父类方法执行");
}
}
class Teacher extends Employee {
public void method(){
System.out.println("子类方法执行");
}
}
//main方法中
Teacher one = new Teacher();
one.method();//子类方法执行
被重写的父类方法并不能在main方法中直接使用,但可以在重写的子类方法里用【super.方法名()】进行调用
class Employee {
public void method() {
System.out.println("父类方法执行");
}
}
class Teacher extends Employee {
super.method();//调用父类方法
public void method(){
System.out.println("子类方法执行");
}
}
//main方法中
Teacher one = new Teacher();
one.method();//父类方法执行
//子类方法执行
3.4局部变量和成员变量共同重名时的使用
使用规则是:在子类的方法体中,局部变量直接使用,子类的成员变量用【this.变量名】,父类的成员变量用【super.变量名】
//参考代码
class Employee {
int num = 30;//父类成员变量
}
class Teacher extends Employee {
int num=20;//子类成员变量
public void method(){
int num=40;//子类局部变量
System.out.println(num);//40
System.out.println(this.num);//20
System.out.println(super.num);//30
}
}
3.5重写(Override)
重写概念:在继承关系当中,方法名一样,参数列表也相同,但对返回值类型和权限修饰符也有一定要求。
说白了就是父类子类它们的成员方法重名了,此时需要对子类重名的方法进行重写。
//参考代码
class Employee {
public void method() {
System.out.println("父类方法执行");
}
}
class Teacher extends Employee {
@Override
public void method(){//重写父类的方法
System.out.println("子类方法执行");
public void method1(){//子类独有的方法
System.out.println("子类方法执行");
}
}
【注意】:
1.重写(Override)和重载(Overload)之间的区别:重载是方法名一样,但参数列表不相同。
2.@Override写在方法前面,用来检测是不是用来有效的正确重写,只要重写正确,不写并不会对代码质量产生影响。
3.【了解】子类重写方法的返回值必须小于等于父类方法的返回值范围
//参考代码
class Employee {
public Object method() {//Object类包含String类
return "父类方法执行";
}
}
class Teacher extends Employee {
public String method(){
return "子类方法执行";
}
}
4.【了解】重写的子类方法的权限修饰符必须大于等于父类方法的权限修饰符
提示:public > protected > ( default ) > private ; default并不是关键字,而是什么都不写,留空即可。
class Employee {
private Object method() {//权限修饰符为private
return "父类方法执行";
}
}
class Teacher extends Employee {
String method(){//权限修饰符实际上为(default)
return "子类方法执行";
}
}
3.6父子类构造方法的访问特点
【重点】1.子类构造方法中有一个默认隐含的“super()”调用
理解:子类构造方法中隐含super();,会默认调用父类构造方法中无参数类型的!!!
class Employee {
public Employee() {
System.out.println("父类方法执行");
}
}
class Teacher extends Employee {
public Teacher(){
//这一行隐藏着一句 super();这里会调用父类的构造方法
System.out.println("子类方法执行");
}
}
Teacher one = new Teacher();//输出:父类方法执行
//输出:子类方法执行
【重点】2.可以通过super关键字来调用父类重载构造方法
class Employee {
public Employee(int num) {
System.out.println("父类方法执行");
}
}
class Teacher extends Employee {
public Teacher(){
super(10);//正确,调用Employee(int num)方法
System.out.println("子类方法执行");
}
public Teacher(int num){
super();//错误,在父类中没有无参构造方法
System.out.println("子类方法执行");
}//即父类没有Employee()方法
public Teacher(int num,double num){
super(10);//正确,调用Employee(int num)方法
System.out.println("子类方法执行");
}
}
【重难点】3.super的父类构造调用,必须是子类构造方法的第一个语句,不能一个子类构造调用多个super语句!!!
class Employee {
public Employee(){
System.out.println("父类无参构造执行");
}
public Employee(int num) {
System.out.println("父类有参构造执行");
}
}
class Teacher extends Employee {
public Teacher(){
super(10);//正确,super语句必须放在第一句(子类构造方法内)
super();//错误,不能连续调用super语句
System.out.println("子类方法执行");
}
public void method(){
super(10);//错误,只能是构造方法才能调用父类构造方法
}
}
【总结】:子类构造方法必须调用父类构造方法,没有调用则赠送super()去调用父类无参构造方法,有调用则用指定的super语句!!!
4.super关键字的使用方法
1.在子类成员方法中,访问父类成员变量
class Employee {
int num=10;
}
class Teacher extends Employee {
int num=20;
public void method(){
System.out.println(num);//20
System.out.println(super.num);//10
}
}
2.在子类成员方法中,访问父类成员方法
class Employee {
public void method(){
System.out.println("父类方法执行");
}
}
class Teacher extends Employee {
public void method(){
super.method();
}
}
3.在子类构造方法中,访问父类构造方法
【请看3.6】
5.this关键字的使用方法
1.在本类的成员方法中访问本类的成员变量
class Employee {
int num=6;
public void method(){
int num=7;
System.out.println(this.num);//6,为成员变量
System.out.println(num);//7,为局部变量
}
}
2.在本类的成员方法中访问本类的另一个成员方法
class Employee {
public void method1(){
System.out.println("111");
}
public void method2(){
this.method1();//111
System.out.println("222");
}
}
3.在本类的构造方法中访问本类的另一个构造方法,不可以自己调用自己,必须是另一个
class Employee {
public Employee(){
System.out.println("111");
}
public Employee(int num){
this();//访问本类的无参构造
System.out.println("222");
}
}
或者
class Employee {
public Employee(){
this(40);//访问本类的有参构造
System.out.println("111");
}
public Employee(int num){
System.out.println("222");
}
}
【注意】:与super一样,this调用语句必须是该类构造方法的第一个语句,不能同时调用多个this语句,并且this语句不能和super语句同时调用!!!
//参考代码
class Employee {
public Employee(){
System.out.println("111");
}
}
class Teacher extends Employee {
public Teacher(int num){
System.out.println("222");
}
public Teacher(){
this(30);//此时系统不在赠送super()语句
System.out.println("333");
}
}
【注意】:不要出现循环调用,即第一个调用第二个,第二个调用第三个,第三个再调用第一个的情况。
class Employee {
public Employee(){
this(30);//调用带有一个参数的构造
System.out.println("111");
}
public Employee(int num){
this(20,30);//调用带有两个参数的构造
System.out.println("222");
}
public Employee(int num1,int num2){
this();//调用没有参数的构造
System.out.println("333");
}
}