目录
类的继承
类的继承:一种在保持对象差异性的同时共享对象相似性的复用
类声明时,使用关键字extend表示继承关系。关键字左侧为子类,右侧为父类
父类又叫(基类、超类),子类又叫(派生类)
通过继承,子类自动拥有父类的所有成员(成员变量和方法),父类的构造方法不能被子类继承
子类的引用可以访问继承父类成员,父类的引用不能访问子类中独有的成员
权限修饰符:
子类不能继承父类中用private修饰的成员
子类与父类不在同一个包时,不能继承父类中用private修饰和默认的成员
java不支持多继承
方法重写
方法重写(覆写、覆盖)—override(overwrite)
当父类方法不能满足子类需要时,子类可以通过重写父类方法的方式实现
重写的规则
必须有继承、子类才能重写父类方法
重写方法与被重写父类方法
方法名称相同
参数个数、类型、顺序相同
返回类型一致或是协变返回类型
协变返回类型:重写方法的返回类型时被重写方法返回类型的子类(或实现类类型)
private修饰的方法不能被重写
子类方法不能抛出比父类方法更多的异常
非静态方法不能被static修饰的方法重写
static修饰的方法不能被重写,但static修饰的变量和方法都可以被屏蔽
方法内定义局部变量屏蔽类中同名的成员变量
子类继承父类
子类中定义与父类同名的成员变量时,在子类范围内,屏蔽父类的成员变量
子类某成员方法重写父类方法,在子类的范围内,屏蔽父类的成员方法
子类某静态方法与父类方法同名,在子类的范围内,屏蔽父类的方法
方法重载和重写的比较
相同点:方法名相同
不同点:
1.使用条件:
方法重写必须有继承、在子类中重写;方法重载在同一个类中
2.参数:
方法重写的参数类型、个数、顺序一致;方法重载参数类型、个数、顺序至少一个不一致
3.返回类型
方法重写返回值类型必须一致或可协变
(协变返回类型:重写方法的返回类型时被重写方法返回类型的子类(或实现类类型))
方法重载对返回类型无要求,可以一致或不一致
4.次数
父类的一个方法只能被一个子类重写一次
一个类中可以有一个方法的多个重载方法
5.权限与异常
方法重写对方法的访问权限和抛出的异常有特殊要求
(不能修改父类的访问权限,不能抛出比父类更多的异常)
方法重载没有限制
作用域
方法内定义局部变量屏蔽类中同名的成员变量
子类继承父类:
1.子类中定义与父类同名的成员变量时,在子类范围内,屏蔽父类的成员变量
2.子类某成员方法重写父类方法,在子类的范围内,屏蔽父类的成员方法
3.子类某静态方法与父类方法同名,在子类的范围内,屏蔽父类的方法
super关键字
super:代表本类继承的直接父类当前的对象
用法:
1.在子类构造方法中通过super关键字调用这个类的父类的构造方法
1)构造方法调用顺序:根基类、父类的父类、父类、子类
2)默认用无参的构造方法
3)父类若无无参构造方法,必须在子类中显示调用父类的构造方法,否则编译报错
4)注意:只能放在方法第一行,this()与super()不能在同一方法中使用
2.实例方法内局部变量或参数与成员变量同名,成员变量在实例方法内被屏蔽时,可以使用super关键字调用
注意:静态方法不能使用this和super关键字
final关键字
final修饰的类不能被继承,因此没有子类
final修饰的方法不能被重写
private、static修饰的方法不能被重写,默认为final修饰
final可以用来修饰常量
final修饰方法的形参,不能改变形参的值
代码演示
//Person01
public class Person01 {
String name = "张飞";
private int age = 40;
public Person01(int a){
System.out.println("父类的构造方法");
}
public void method(){
System.out.println("父类中的方法");
}
public void work(){
System.out.println("父亲的工作是挣钱养家");
}
}
//Student02
//继承关键字extend表示继承关系。关键字左侧为子类,右侧为父类
//父类又叫基类还叫超类,子类又叫派生类
//继承只有单继承不能多继承
public class Student02 extends Person01 {
//父类和子类的属性或者方法(完全一样),那么在子类范围内将父类的成员屏蔽掉
String name = "张三";
//当父类的成员不能满足子类需要的时候可以通过方法重写来解决
//方法重写的条件是:
//1.要有继承关系,且在子类中进行方法重写
//2.方法名相同
//3.参数的个数,类型,顺序完全一致
//4.返回值类型相同或者协变
//协变返回值类型表示返回值类型是当前类型的子类类型
@Override
public void work() {
//super表示父类的对象,
//所以super的第一种用法是:当父类成员和子类成员同名的时候,在子类范围内会将父类的成员屏蔽掉,通过super调用父类的成员
//super的第二种用法是:在子类的构造方法内调用父类的构造方法
System.out.println(name);
System.out.println(super.name);
System.out.println("学生的工作是努力学习");
}
public Student02(){
//如果父类是无参的构造方法,子类默认调用父类的构造方法
// super();//默认调用无参
//但是如果是有参的构造方法,子类必须显示调用父类的构造方法,否则编译报错
super(1);//调用父类的构造方法只能放在第一行上
System.out.println("子类的构造方法");
}
//父类中的构造方法不能被子类继承
public static void main(String[] args) {
Student02 s = new Student02();
//通过继承子类会自动拥有父类的所有成员
// System.out.println(s.name);
//private修饰的成员不能被子类继承
// System.out.println(s.age);
// s.method();
s.work();
}
}
class Test extends Teacher04{
public void method(){
//不同包下的派生类可以继承public和protected修饰的成员
Test t = new Test();
System.out.println(t.age);
System.out.println(t.no);
// System.out.println(t.name);
// System.out.println(t.score);
}
}
//FinalTest03
public class FinalTest03 {
//final不能修饰构造方法
// public final FinalTest03(){}
//final可以修饰方法
public final void method(){
//final 可以修饰变量,也就是我们说的常量
final int A = 10;
}
}
//final可以修饰类
//final修饰的类能继承其它的类,但是不能被其它类继承
final class Test01 extends Test02{}
class Test02 extends FinalTest03{
//final修饰的方法不能被重写,但是可以被继承,能正常使用
// public void method(){
// //final 可以修饰变量,也就是我们说的常量
// final int A = 10;
// }
public void doSomething(){
method();
}
}
//final修饰的类不能作为父类,也就是没有子类
//class Test03 extends Test01{}