概念

继承是从已有的类中派生出新的类,新的类能吸收已有类的属性和行为,并能扩展新的属性和行为。

Java继承特点

1)Java是单继承的,不支持多继承。这样使得Java的继承关系很简单,一个类只能有一个父类,易于管理程序。同时一个类可以实现多个接 口,从而克服单继承的缺点。

java 中只支持单继承,并且是链式继承(爹不能再继承儿子)

2)继承关系是传递的

3)private修饰的成员变量或方法是不能被继承的

解决什么问题

提高了代码的效率,避免了代码重写

继承的目的

代码复用

语法格式

[修饰符] class 子类 extends 父类{
//类体
}

public static void main(String[] args){
	Cat c = new Cat();
	Dog d = new Dog();
	Bird b = new Bird();
	eat(c);
	//输出结果为 猫吃鱼
	eat(d);
	//输出结果为  狗吃肉
	eat(b);
	//输出结果为 动物吃东西
}

//创建一个动物类 ,作为父类
class Animals{
	public void eat(){
		Systeam.out.println("动物吃东西");
	}
}

//创建一个猫类继承动物类,作为子类
class Cat extends Animal{
	public void eat() {
		System.out.println("猫吃鱼");
	}
}
//创建一个狗类继承动物类,作为子类
class Dog extends Animal{
	public void eat() {
		System.out.println("狗吃肉");
	}
}
//创建一个鸟类继承动物类,作为子类
class Bird extends Animal{	
}

上面的代码中,cat,dog,bird都继承了父类动物类,
cat和dog类进行了覆写 所以输出的是子类的覆写内容,这个后面会提到
bird类继承了动物类,继承了父类的属性,没有进行重写,所以输出的是父类输出的内容

java中的根类 : Object
如果一个类没有显示继承其他类,那么该类默认继承 java.lang.Object

Super

保存了父类型特征,可以理解为是父类的对象引用(错的)

语法
super(参数);
必须在子类构造方法的第一行
如果 子类构造方法中 没有出现 this(xxx) 和 super(xxx)的话 会默认有一个super() 去调用父类的无参构造
this(xxx) 这种写法必须出现在构造方法第一行,所以 this(xxx) 和 super(xxx) 不能同时出现
this和super都不能出现在静态上下文中

用法
1 用在子类成员方法,可以区分子类和父类同名的成员变量/成员方法
2 用在子类构造方法,同上
3 用在子类构造 方法中,用于调用父类构造方法

public class Super_01 {
	Super_01(){
		//不写,默认会有super()调用父类无参构造
		super();
		System.out.println("子类构造方法");
	}
	int i = 2;
	

	public static void main(String[] args) {
		Super_01 s = new Super_01();
		s.m1();

	}
	public void m1() {
		//子类
		System.out.println("i");
		//父类
		System.out.println("super.i");
		//子类
		System.out.println("this.i");
	}

}
class A{
	A(){
		super();
		System.out.println("父类构造方法");
		
	}
	int i = 10;
}
如果构造方法私有化,就不能再有其他类继承该类
	 因为子类想要实例化对象,必须在构造方法中,调用父类的构造方法
	   如果父类构造方法私有化,那么子类调用不到,报错
public class Super_02 {
	public Super_02() {
		super();
	}

}
class B{
	//private B() {}
	public B() {}
}

构造方法可以和静态方法/成员方法重名吗?
静态方法/成员方法的方法名可以和类名相同吗?
可以

如何区分?
看返回值,构造方法 没有返回值,连void都没有

public static void main(String[] args) {
		new Super_03();

	}
	//成员方法
	public void Super_03(){
		System.out.println("1111111111法");
	}
	//构造方法
	public Super_03(){
	System.out.println("22222222222");
	}
package _08_Super;

public class Super_04 {

	public static void main(String[] args) {
		new Sub();

	}

}
class Sub extends Sup{
	{
		System.out.println("子类实例代码段1");
	}
	static {
		System.out.println("子类静态代码段1");
	}
	Sub(){
		//super();
		this(2);
		//---------
		System.out.println("子类构造方法");
		
	}
	Sub(int i){
		super();
	}
}
class Sup{
	static {
		System.out.println("父类静态代码段1");
	}
	{
		System.out.println("父类实例代码段1");
	}
	Sup(){
		super();
		//--------
		System.out.println("父类构造方法");
	}
}

Override(重写,覆写)

继承之后 子类必须和父类一模一样吗?
不需要

概念
1 子类有特有的属性,比如 父类只有m1 , 子类中 还有 m2 ,这个m2 就是子类特有,父类没有

2 子类和父类拥有相同名字的方法,但是功能不一样,叫覆写/重写/覆盖

覆写 特指成员方法,和其他属性无关

什么时候需要进行覆写?
当父类方法无法满足子类的业务需求时,需要对父类方法进行覆写
前提条件
1 必须有继承关系的体系中
2 不能比原方法有更低的访问权限 >=
3 错误不能越来越多,不能有更宽泛的异常 <=
4 方法名,返回值,参数列表 都必须一致
方法名不一致,说明是俩方法
参数列表不一致,是方法重载
返回值表示方法的功能,必须一样,不能更改方法的本质

继承的目的
代码重用

继承最重要的功能
方法覆写

重写的意义
功能越来越强
使用范围越来越广
错误越来越少

用之前继承举例的代码来解释

public static void main(String[] args){
	Cat c = new Cat();
	Dog d = new Dog();
	Bird b = new Bird();
	eat(c);
	//输出结果为 猫吃鱼
	eat(d);
	//输出结果为  狗吃肉
	eat(b);
	//输出结果为 动物吃东西
}

//创建一个动物类 ,作为父类
class Animals{
	public void eat(){
		Systeam.out.println("动物吃东西");
	}
}

//创建一个猫类继承动物类,作为子类
class Cat extends Animal{
	//方法覆写,重写了父类的eat()方法,输出为子类覆写内容
	public void eat() {
		System.out.println("猫吃鱼");
	}
}
//创建一个狗类继承动物类,作为子类
class Dog extends Animal{
	//方法覆写,重写了父类的eat()方法,输出为子类覆写内容
	public void eat() {
		System.out.println("狗吃肉");
	}
}
//创建一个鸟类继承动物类,作为子类
class Bird extends Animal{	
//未进行方法的覆写,所以继承父类的属性,输出父类的内容
}

Final

被Final修饰的
类 : 不能被继承
成员方法 : 不能被覆写
修饰的变量 : 不能二次赋值,并且没有默认值,在整个程序的生命周期中,值不能被改变

常量
整个程序生命周期中,值不会被更改 / 使用final修饰的变量就是常量, 字面量也是常量

分类
静态常量:(final修饰的静态变量,一般是public static final ,由于是公共的,和对象没有关系,所以应用较多)
所以 一般我们把 final修饰的静态变量 叫常量
成员常量
局部常量
命名规则 建议 全大写,在eclipse中 使用 蓝色、斜体 、 加粗 显示

public class Final_01 {
	public static final int C = 2;
	final int i =2;
	final int a;
	//final修饰的变量没有默认值,必须显示赋值
	Final_01(int i){
		a = i;
	}
	

	public static void main(String[] args) {
		Final_01 f = new Final_01(2);
		//final修饰的变量不能被更改
		//f.i = 3;
		System.out.println(123);

	}

}
//final class A{
class A{
	//修饰的成员方法不能被覆写
//	public final void m1() {
		
	//}
}
class B extends A{
	//class B{
         public void m1() {}	

}