Java继承面试知识点总结

继承

利用继承,人们可以基于已存在的类构造一个新类,继承已存在的类就是复用(继承)这些类的方法和域。在此基础上,还可以添加一下新的方法和域,以满足新的需求。

覆盖方法

简答的代码示例:

public class Employee {
    private String name;
    private double salary;
    private LocalDate hireDay;

    public Employee(String name, double salary, int year, int month, int day) {
        this.name = name;
        this.salary = salary;
        this.hireDay = LocalDate.of(year, month, day);
    }

    public String getName() {
        return name;
    }

    public double getSalary() {
        return salary;
    }

    public LocalDate getHireDay() {
        return hireDay;
    }

    public void raiseSalary(double byPercent) {
        double raise = salary * byPercent / 100;
        salary += raise;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "name='" + name + '\'' +
                ", salary=" + salary +
                ", hireDay=" + hireDay +
                '}';
    }
}
public class Manager extends Employee {
    private double bonus;

    public Manager(String name, double salary, int year, int month, int day) {
        // Manager 类的构造器不能访问 Employee 类的私有域,所以必须利用 Employee 类的构造器对这部分私有域进行初始化, 且使用 super 调用构造器的语句必须是子类构造器的第一条语句。
        super(name, salary, year, month, day);
        this.bonus = 0;
    }

    public void setBonus(double bonus) {
        this.bonus = bonus;
    }

    public double geSalary() {
        double baseSalary = super.getSalary();
        return baseSalary + bonus;
    }
}

上述两个类中,Manager 和 Employee 之间是 “is-a" 的关系” “is-a”是继承的一个明显特征, 根据继承的定义, Manager 类继承了 name, salary, hireDay 三个域以及对应的三个 get 访问器方法。将通用的方法放在超类中,而将具有特殊用途的方法放在子类中,在面向对象程序设计中十分普遍。

需要注意:

Manager 类的 getSalary 方法不能直接访问父类的私有域, 只有父类才能访问其私有域,因此需要父类提供一个访问 salary 的公共接口,通过 super 关键字调用。

super 与 this 的不同:

super 不是一个对象的引用,不能将 super 付给另一个对象变量,它只是一个指示编译期调用超类方法的特殊关键字。

父类与子类构造器的关系

  • 当子类没有带参构造器和无参构造器,父类有带参构造器和无参构造器时, 子类会有默认的无参构造器,并且该无参构造器会默认调用父类无参构造器的方法。
public class ExtendsTest {
    public static void main(String[] args) {
        Son son = new Son(); 
    }
}

class Father {
    private int age;

    public Father() {
        System.out.println("Father no argument constructor");
    }

    public Father(int age) {
        this.age = age;
    }
}

class Son extends Father {
}
// output
// Father no argument constructor
  • 当子类没有带参构造器和无参构器,父类只有带参构造器时编译时检查会报错,因为当写了带参构造器时系统不会给出默认的无参构造器,此时子类不能调用父类的默认无参构造器。
class Father {
    private int age;

    public Father(int age) {
        this.age = age;
    }
}

class Son extends Father { // error There is no default constructor available in Father
}
  • 当子类没有带参构造器而有无参构器,且父类同时有带参构造器和无参构造器时,子类的无参构造器在第一行默认调用父类的无参构造器。
public class ExtendsTest {
    public static void main(String[] args) {
        Son son = new Son();
    }
}

class Father {
    private int age;

    public Father() {
        System.out.println("Father no argument constructor");
    }

    public Father(int age) {
        this.age = age;
    }
}

class Son extends Father {
    private String name;

    public Son() {
        System.out.println("Son no argument constructor");
    }
}
// output
// Father no argument constructor
// Son no argument constructor

总结

  • 如果子类的构造器没有显示地调用超类的构造器,则会自动地超类默认(没有参数)的构造器,若父类只存在带惨构造则不会有默认的无参构造器。
  • 如果父类没有无参构造器,并且子类的构造器又没有显示地调用父类的其他构造器,则Java编译期将报告错误。

final

如果类用 final 修饰,其他类就不能继承它,如果方法用 final 修饰,子类就不能重写它, 如果类中的域用 final 修饰,这个域在构造对象完成之后就不能被修改。final 修饰符的主要作用为:确保被修饰的对象在子类中不会改变语义。

注意:

  • final 修饰类时,类中方法自动变成 final, 但不包括域。
  • 如果方法很简单,被频繁调用且没有真正地被覆盖,那么及时编译器会将这个方法进行内联处理(inline),例如内联调用 e.getName() 会被替换为访问 e.name 域。

强制类型转换

进行类型转换的唯一原因是:在暂时忽视对象的实际类型之后,使用对象的全部功能。在 Java 中,每个对象变量都属于一个类型,类型描述了这个变量所引用的以及能够引用的对象类型。

Java 是强类型语言,在将一个值存入变量时,编译器将检查是否允许该操作,将一个子类的引用复制给一个超类变量,编译器时允许的(向上转型,此时会丢失子类扩展的方法),但将一个超类的引用复制给一个子类变量(向下转型,此时可以找回子类扩展的方法),必须进行类型转换,这样才能通过运行时检查。

一般只有在使用子类中的特有方法是才需要进行强制类型转换,此时可以使用 instanceof 先检查类型,再进行类型转换。

Employee[] staff = new Employee[3];
Manager boss = new Manager();
staff[0] = boss;
staff[1] = new Employee();
if (staff[1] instanceof Manager) {
	boss = (Manager) staff[1];
}

注意:

null instanceof C // false,不会报错,因为null没有引用任何对象,当然也不会引用C类型对象

本文章与github上同步,欢迎来玩,提交issue。

Reference

1.[Java核心技术·卷 I(原书第10版)](继承

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
java核心知识点整理 1.Java中没有多继承,而是用接口来代替多继承 2.运行一个已经编译的程序时,Java解释器总是从指定类的main方法中的代码开始执行,因此,执行代码中必须有一个main函数。 3.Java是典型的强类型语言,即必须声明变量的类型,Java中有8种类型,6种数值类型(4个整数型和2个浮点型)、一个字符类型和一个boolean类型。 想学习java可以来这个群,首先是二二零,中间是一四二,最后是九零六,里面有大量的学习资料可以下载。 4.强制类型转换: int nx = (int) x; // (语法:用圆括号将目标类型括起来,后面跟上要转换的变量); 5.Java不能为单独的方法,如main方法,定义局部常量,而只能为类定义常量,供该类的所有方法使用,所以,通常称之为类常量。如: class UsersConstants{ 2public static final double g = 32; public static final double main(String[] args){ System.out.println(g); } } 注意:常量定义于main方法的外边,而且必须有关键字 static final; 6.字符串的子串: String str = hello”“; String str1 = str.substring(0,4); //输出hell 7.不要用==运算符来测试两个字符串是否相等,该运算符只能判断两个字符串是否存在同一个位置。 用equals. String str = “hello”; str.equals(”hell”); // return false; 8.对象的行为、状态、标识 9.面向过程与OOP

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值