继承
继承
继承可以解决代码复用,让我们的编程更加靠近人类思维。当多个类存在相同的属性(变量)和方法时,可以从这些类中抽象出父类,在父类中定义这些相同的属性和方法,所有的子类不需要重新定义这些属性和方法,只需要通过extends来声明继承父类即可。
1、继承的好处:
- 代码的复用性提高了
- 代码的可扩展性和可维护性提高了
2、继承的细节:
- 子类继承了所有的属性和方法,非私有的属性和方法可以在子类中直接访问,但是私有属性和方法不能在子类直接访问,要通过父类提供的公共的方法去访问。
private int age;
// 提供公共方法访问私有属性
public int getAge(){
return age;
}
private void test(){
System.out.println("test");
}
// 提供公共方法访问私有方法
public void callTest(){
test();
}
- 子类必须调用父类的构造器,完成父类的初始化
- 当创建子类对象时,不管使用子类的哪个构造器,默认情况下总会去调用父类的无参构造器,如果父类没有提供无参构造器,则必须在子类的构造器中用
super
去指定使用父类的哪个构造器完成对父类的初始化工作,否则,编译不会通过 - 如果希望指定去调用父类的某个构造器,则显式的调用一下:
super(参数列表)
- super在使用时,必须放在构造器第一行(super只能在构造器中使用)
super()
和this()
都只能放在构造器第一行,因此这两个方法不能共存在一个构造器- java所有类都是Object类的子类, Object是所有类的基类
- 父类构造器的调用不限于直接父类!将一直往上追溯直到Object类(顶级父类)
- 子类最多只能继承一个父类(指直接继承),即java中是单继承机制。
- 不能滥用继承,子类和父类之间必须满足
is-a
的逻辑关系
3、继承的本质:
创建子类对象时,内存中发生了什么?
package day01;
public class ExtendsTheory {
public static void main(String[] args) {
// ?->这时请大家注意,要按照查找关系来返回信息
// (1)首先看子类是否有该属
// (2)如果子类有这个属性,并且可以访问,则返回信息
// (3)如果子类没有这个属性,就看父类有没有这个属性(如果父类有该属性,并且可以访问,就返回信息..)
// (4)如果父类没有就按照(3)的规则,继续找上级父类,直到0bject. . .
Son son = new Son();
System.out.println(son.name);
}
}
class Grandpa {
String name = "大头爷爷";
String hobby = "旅游";
}
class Father extends Grandpa {
String name = "小头爸爸";
int age = 39;
}
class Son extends Father {
String name = "大头儿子";
}
4、继承练习:
// 练习一:
package day01;
public class Demo3 {
public static void main(String[] args) {
B b = new B();
}
}
class A {
A(){
System.out.println("a");
}
A(String name){
System.out.println("a name");
}
}
class B extends A{
B(){
this("abc");
System.out.println("b");
}
B(String name){
System.out.println("b name");
}
}
输出结果:a
b name
b
// 联系二:
package day01;
public class Demo3 {
public static void main(String[] args) {
C c = new C();
}
}
class A {
A(){
System.out.println("我是A类");
}
}
class B extends A{
B(){
System.out.println("我是B类无参构造");
}
B(String name){
System.out.println(name + "我是B类有参构造");
}
}
class C extends B{
C(){
this("hello");
System.out.println("我是C类无参构造");
}
C(String name){
super("hahah");
System.out.println("我是C类有参构造");
}
}
输出结果: 我是A类
hahah我是B类有参构造
我是C类有参构造
我是C类无参构造
// 练习三:
package day01;
public class Demo4 {
public static void main(String[] args) {
PC pc = new PC("intel", 16, 512, "Dell");
pc.printInfo();
NotePat notePat = new NotePat("intel", 16, 512, "red");
notePat.printInfo();
}
}
class Computer {
private String cpu;
private int memory;
private int disk;
public Computer(String cpu, int memory, int disk) {
this.cpu = cpu;
this.memory = memory;
this.disk = disk;
}
public String getCpu() {
return cpu;
}
public void setCpu(String cpu) {
this.cpu = cpu;
}
public int getMemory() {
return memory;
}
public void setMemory(int memory) {
this.memory = memory;
}
public int getDisk() {
return disk;
}
public void setDisk(int disk) {
this.disk = disk;
}
@Override
public String toString() {
return "Computer{" +
"cpu='" + cpu + '\'' +
", memory=" + memory +
", disk=" + disk +
'}';
}
}
class PC extends Computer{
private String brand;
public PC(String cpu, int memory, int disk, String brand) {
super(cpu, memory, disk);
this.brand = brand;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public void printInfo(){
System.out.println("info:");
System.out.println(toString() + " brand = " + brand);
}
}
class NotePat extends Computer{
private String color;
public NotePat(String cpu, int memory, int disk, String color) {
super(cpu, memory, disk);
this.color = color;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public void printInfo(){
System.out.println("info:");
System.out.println(toString() + " color = " + color);
}
}
输出结果:info:
Computer{cpu='intel', memory=16, disk=512} brand = Dell
info:
Computer{cpu='intel', memory=16, disk=512} color = red