继承:Object 是所有类的一个祖先类。 class A 约等于class A extends Object。
继承的作用:代码的复用性问题,在已有的基础上进行功能扩充。(继承要表达的是逻辑之间有关系的类)
继承的语法:java中使用 extends 关键字来实现
class 子类 extends 父类
其他名称:子类(child),派生类(Derived class)
父类(parent),基类(Base 类),超类(Super 类)
子类继承父类,那么父类的方法,属性在子类中也有一份,除了 private 修饰的属性,其他的访问限定符都可以访问父类属性。如果是访问的方法中含有 private 属性,那么不受影响依旧可以访问。
访问限定 | 子类能否访问父类方法或属性 |
public / protected | 可以 |
default | 在一个包中时可以 |
private | 不可以 |
继承中名字遮挡的问题:(属性和方法道理相同)
变量名 | 是否有歧义 | 解释 |
a | 是 | 1.局部变量/形参a 2.属性中的a(本类属性a/父类属性a) 3.外部类中的a |
this.a | 是 | 属性中的a(本类属性a/父类属性a) |
super.a | 否 | 父类的属性a |
Outter.this.a | 否 | 外部类的属性a |
代码块:普通代码块:定义在方法中的代码块
构造块:定义在类中的代码块(不加修饰符)
构造块优先于构造方法执行,每产生一个新的对象就调用一次构造块,构造块可以进行简单的逻辑操作(在调用构造方法前)
静态代码块:使用static定义的代码块。静态块的主要作用是为 static 属性进行初始化
非主类定义的静态块:1.静态块优先于构造块执行。2. 无论产生多少实例化对象,静态块都只执行一次。
在主类中定义的静态块,优先于主方法(main)执行
静态内部类:
定义在类的成员级别并且被 static 修饰的一种类
class LinkedList{
public/default/protected/private class Node{
int val;
Node next;
}
}
最大的作用就是一个类从概念上应该属于另一个的范围。
使用上:(1)在LinkedList 内部使用,和普通类没有区别:Node n = new Node();
(2)在LinkedList 外部使用,指明所属关系:LinkedList.Node n = new LinkedList.Node();
继承的限制:
1. 只允许单继承,不允许多重继承,但是允许多层继承。
//错误的,不能多重继承
class A{}
class B{}
class C extends A,B{}
//允许的多层继承
class A{}
class B extends A{}
class C extends B{}
2. 父类与子类的关系:
(1)类加载关系:子类的加载不许出发父类的加载(即父类的加载一定发生在子类之前)
(2)对象实例化 / 构造的关系:父类的属性初始化一定发生在子类属性初始化之前(即子类的对象构造的过程会触发父类中属性的初始化过程)。
属性的初始化:(1)定义时初始化 + 构造代码块按顺序 (2)构造方法。和 super 调用父类构造方法的位置无关。
方法重写(覆写)(Overide):
子类重写了父类的方法,那么子类和父类的方法 方法名称相同,形参列表相同,返回值类型相同(允许返回父类方法返回值类型的子类)。访问限定符:被覆写不能够拥有比父更更为严格的访问控制权限(不能比父类的更封闭)。
现在已经接触了了三种访问控制权限: private < default < public 。那么也就意味着如果父类使用 public 进行方法声明,那么子类必须也使用 public;如果父类使用 default,那么子类可以使用 default 或者 public 。
Supper关键字
(1)用来访问父类构的造方法。
(2)super 不是引用,在进行覆写的操作过程之中,子类可以使用 super. 方法 () / super. 属性 ,明确访问父类的属性或方法,显示调用父类的构造方法时,必须出现在第一行。
final关键字
1.修饰变量,表示不可变变量,必须在声明时赋值,并且不不能够被修改。
final int a = 10;
a = 100;//触发编译错误
final int[] a = new int[10];
---- a = new int[100];//触发编译错误
---- a[0] = 10;//正确的
//被 final 修饰表示不能指向其他的引用
final Person p = new Person();
---- p = null;//触发编译错误
---- p.name = "zhangsan";//正确的
2.修饰类:表示这个类不能被继承(不允许有子类)。final 一旦修饰一个类之后,该类的所有方法默认都会加上 final 修饰(不包含成员变量)。
final class A{} //那么 A 类不能被继承,里面的方法不能被重写
3.修饰方法:代表这个方法不能被其子类覆写。
class A { final void method() }//那么方法 method不能被重写,A类可以被继承
Java校招笔试题:
public class HelloA {
//构造方法
public HelloA(){
System.out.println("Hello A!父类构造方法");
}
//非静态代码块
{
System.out.println("i'm A class.父类非静态代码块");
}
//静态代码块
static{
System.out.println("static A ⽗类静态代码块");
}
}
public class HelloB extends HelloA {
//构造方法
public HelloB(){
System.out.println("Hello B! 构造方法");
}
//非静态代码块
{
System.out.println("i'm B class.非静态代码块");
}
//静态代码块
static{
System.out.println("static B 静态代码块");
}
public static void main(String[] args) {
System.out.println("---start---");
new HelloB();
new HelloB();
System.out.println("---end---");
}
}
输出:
static A 父类静态代码块
static B 静态代码块
---start---
i'm A class.父类非静态代码块
Hello A!父类构造方法
i'm B class.非静态代码块
Hello B! 构造方法
i'm A class.父类非静态代码块
Hello A!父类构造方法
i'm B class.非静态代码块
Hello B! 构造方法
---end---