一.继承
1.继承
继承:关键字extends 来表示继承关系,若没有指明所要继承的类,默认继承为Object类
public class father {
public father(){}
}
public class son extends father{
public son(){}
}
如上所示,son继承于father,所以father类为父类,son类为子类,并且子类可以继承父类的变量和方法。
- 变量
- 子类可以继承父类的所定义的变量并使用,但也并不是完成继承
- private修饰符修饰的变量无法继承,只能继承public和protected修饰的变量
- 若子类中的变量与父类中已存在的变量重名,那么子类的变量将会覆盖父类的变量。
- 方法
- 方法也和变量的继承规则类似。
- 构造器
- 子类无法继承父类的构造方法,并且子类的构造方法中还要调用父类的构造方法构建实例,而是放在构造方法的第一行。
- 子类构造器中存在父类构造器的原因:子类中部分的方法和变量来源于父类,如果想要调用的话,必须要让父类存在父类的实例对象。
class father {
public father() {}
public father(String name) {}
}
class son extends father{
public son() {
super();
}
}
- 子类的构造器中默认调用父类的无参数构造器,并且系统会自动调用。若父类没有无参数构造器,那么子类构造器中需要手动super关键字来进行显示地手动调用。
2.关键字
- this关键字的作用
- this通常作为隐式参数出现,表示当前的类对象
- 可以通过该类对象调用变量,方法,构造器(调用构造器需要放在构造方法的第一行)。
public class father {
private String name = "王三";
public father() {}
public father(String name) {
//调用无参数构造器,必须在第一行
this();
}
public void run() {
//调用变量
String name1 = this.name;
}
public void jump() {
//调用方法
this.run();
}
}
- super关键字的作用
- super的作用与this类似,只不过super表示的是父类对象。
3.多态
- 重写,前提为继承,父类与子类中具有相同方法名,返回值,形式参数的方法,改变方法内的核心内容,实现对父类方法的覆盖,有种一样的外壳,但本质不变,static,final修饰的方法除外。
- 多态
父类引用不同子类的实例,子类中都具有相同的run方法,在方法run()方法运行的时候,虚拟机会根据实际引用的对象类型,来执行正确的方法。
class father {
public father() {}
public void run() {}
}
class son1 extends father{
public son1() {
}
public void run() {
System.out.println("son1在奔跑");
}
}
class son2 extends father{
public son2() {
}
public void run() {
System.out.println("son2在奔跑");
}
}
public class test{
public static void main(String[] args) {
father son1 = new son1();
father son2 = new son2();
son1.run();
son2.run();
}
}
4.随手摘的面试题
- 第一题
class Fu {
public int num = 10;
public Fu() {
System.out.println("fu");
}
}
class Zi extends Fu {
public int num = 20;
public Zi() {
System.out.println("zi");
}
public void show() {
int num = 30;
System.out.println(num);
System.out.println(this.num);
System.out.println(super.num);
}
}
class ExtendsTest {
public static void main(String[] args) {
Zi z = new Zi();
z.show();
}
}
- 很简单,考察要点:子类构造器中存在父类构造器,this,super的用法
- 答案:fu,zi,30,20,10
- 第二题
public class Test {
public static void main(String[] args) {
new Circle();
}
}
class Draw {
public Draw(String type) {
System.out.println(type+" draw constructor");
}
}
class Shape {
private Draw draw = new Draw("shape");
public Shape(){
System.out.println("shape constructor");
}
}
class Circle extends Shape {
private Draw draw = new Draw("circle");
public Circle() {
System.out.println("circle constructor");
}
}
- 该题考察类的加载顺序,虚拟机在加载类时,若发现父类没有加载,会将父类优先加载。先执行初始化过程,再执行构造器。若不知道初始化过程,可以去看看类加载机制。
- 结果
shape draw constructor
shape constructor
circle draw constructor
circle constructor
- 第三题
class Fu {
static {
System.out.println("静态代码块Fu");
}
{
System.out.println("构造代码块Fu");
}
public Fu() {
System.out.println("构造方法Fu");
}
}
class Zi extends Fu {
static {
System.out.println("静态代码块Zi");
}
{
System.out.println("构造代码块Zi");
}
public Zi() {
System.out.println("构造方法Zi");
}
}
class ExtendsTest2 {
public static void main(String[] args) {
Zi z = new Zi();
}
}
- 本题考察代码块,静态代码块,构造方法的执行顺序。执行顺序为静态代码块>代码块>构造方法
- So,结构:
静态代码块Fu
静态代码块Zi
构造代码块Fu
构造方法Fu
构造代码块Zi
构造方法Zi