1.继承基本介绍:
继承可以解决代码复用,让我们的编程更加靠近人类思维,当多个类存在相同的属性(变量)和方法时,可以从这些类中抽像出父类,在父类中定义这些相同的方法和属性,所有子类可以继承父类,子类可以不再需要定义这些属性和方法,只需要通过extends来声明继承父类。
继承基础
class 子类 extends 父类{}
例如:
//父类 是pupil和Graduate的父类
class Student {
// 共有属性
public String name;
public int age;
private double score;
//共有方法
public void setScore(double score) {
this.score = score;
}
// public void testing(){
// System.out.println("学生"+name+"正在。。。。");
// }
public void showInfo(){
System.out.println("学生 姓名 name = "+ name + "\t" +"年龄"+ age + "\t"+"成绩"+score);
}
}
class Pupil extends Student {
public void testing(){
System.out.println("学生"+name+"正在。。。。");
}
}
package com.hspedu.extend_.improve;
public class Graduate extends Student{
public void testing(){
System.out.println("学生"+name+"正在。。。。");
}
}
public class Extemd01test {
public static void main(String[] args) {
com.hspedu.extend_.Pupil pupil = new Pupil();
pupil.name = "汤亚波";
pupil.age = 10;
pupil.setScore(100);
pupil.showInfo();
com.hspedu.extend_.Graduate graduate = new Graduate();
graduate.name = "狗东西";
graduate.age = 20;
graduate.setScore(60);
graduate.showInfo();
}
}
关于继承的细节
一: 子类必须调用父类的构造器,完成父类的初始化。
在调用子类时,子类会先在父类完成初始化,在回到子类完成初始化。
二: 子类继承父类所有的属性和方法,但是私有的属性和方法不能在子类中直接访问,要通过公共的方法访问。
三: 当创建子类对象时,不管使用子类的哪个构造器,默认情况下总会去调用父类无参构造器,如果父类没有提供无参构造器,则必须在子类的构造器中用super去指定使用父类的哪个构造器完成对父类的初始化工作,否则无法编译通过。
四: 如果希望指定父类的某个构造器,则显式的调用一下:super(参数列表) 参数列表为 所调用的构造器的参数列表。
五: super在使用时,必须放在第一行。
六: 在子类构造器中super(参数列表)和this(参数列表)都只能放在第一行,所以super()和this()不能同时出现在子类构造器中,this()是调用本类的其他构造器
七: 在子类中访问父类私有属性和方法,需要在父类中创建public方法调用父类的私有属性和方法,则子类直接访问所创建的方法即可。
public class Base {//父类
public int n1 = 100;//共有属性
protected int n2 = 200;
int n3 = 300;
private int n4 = 400;//私有属性 子类无法直接访问
public Base(){//无参构造器
System.out.println("Base()...");
}
public Base(String name){
System.out.println("Base(String name)...");
}
public void test100(){
System.out.println("test100");
}
public void test200(){
System.out.println("test200");
}
public void test300(){
System.out.println("test300");
}
private void test400(){//私有方法 子类无法直接访问
System.out.println("test400");
}
// 提供公共方法访问私有属性和方法
public int getN4() {
return n4;
}
public void callTest400(){
test400();
}
}
package com.hspedu.extend_.details;
//ctrl + H 继承关系
public class Sub extends Base{//子类
int age;
public Sub(){//子类构造器
//super();//默认调用父类的无参构造器
// tihs("jeck",20);不能与super 放在一起使用
super("汤亚波");//调用父类 public Base(String name) 构造器
System.out.println("Sub()....");
}
public Sub(String name,int age){
// super();//父类的无参构造器
// 什么都不写 默认为父类的无参构造器
super("汤亚波");
this.age = age;
}
public void sayOK(){
// 非私有属性和方法可以访问
System.out.println(n1+" "+n2+" "+n3);
System.out.println("n4 = " + getN4());
test100();
test200();
test300();
// test400();//私有方法无法直接访问
callTest400();//
}
}
继承的本质分析
class Grandpa{
String name = "大头爷爷";
String hobby = "旅游";
public Grandpa(){
// 构造器
}
}
class Father extends Grandpa{
String name = "大头爸爸";
private int age = 33;
//存在无参默认构造器
public int getAge() {
return age;
}
}
class son extends Father{
String name = "汤亚波";
}
继承的内存布局
继承查找关系
1.先从子类查找起,如果子类存在该属性或者方法,并且可以访问(不为private修饰),则返回信息,如果子类不存在该属性或者方法,则开始查找父类
2.利用 super.属性 或者 super.方法() 可直接访问父类的属性和方法
public class Extend {
public static void main(String[] args) {
son son = new son();
System.out.println(son.name);
System.out.println(son.getAge());
System.out.println(son.hobby);
// 要按照查找关系来返回信息
// 1.首先要看子类是否有该属性
// 2.如果子类有这属性,并且可以访问,则返回信息
// 3.如果子类没有这属性,就看父类有没有该属性(如果有则返回信息)
// 4.->相同的属性如果私有属性在子类中,则不能访问父类的共有属性
}
}
class Grandpa{
String name = "大头爷爷";
String hobby = "旅游";
public Grandpa(){
// 构造器
}
}
class Father extends Grandpa{
String name = "大头爸爸";
private int age = 33;
public int getAge() {
return age;
}
}
class son extends Father{
String name = "汤亚波";
}