Java学习笔记四(继承)

1 继承

继承的实现: public class 子类 extends父类 {... }

注释:子类可直接使用,父类(保护,公开)的属性和方法

优点:减少重复代码,缺点:只能单继承

java 复制代码
// 父类
public class Test {
	private String str1; //私有
	String str2;         //默认
	protected String str3;// 保护
	public String str4;    //公开
	
	private void fn1() {} //私有
	void fn2() {}         //默认
	protected void fn3() {}// 保护
	public void fn4() {}   //公开
}
java 复制代码
// 子类
public class SubTest extends Test {
    public void subFn1() {
    	String t3 = str3;
    	String t4 = str4;
    	fn3();
    	fn4();
    }
}

2 子类实例化

子类构造器默认先调用父类无参构造器(可省略),父类没有无参构造器(必须先显示调用有参构造器)

java 复制代码
public class 子类 extends 父类 {
    public 子类() {
        [super();] // 可省略
        子类处理...
    }
}

3 方法重写

注释:子类定义了与父类相同的方法(方法重写)

java 复制代码
// 父类
public class Test {
    public String name = "张三";
    public void doTest() {
        System.out.println(name);
    }
}

测试类1:子类未重写方法,调父类方法使用的是父类属性(不会输出子类同名属性)

java 复制代码
// 子类
public class SubTest1 extends Test {
    public String name = "李四";
}
java 复制代码
public class Main {
    public static void main(String[] args) {
        SubTest1 s = new SubTest1(); 
        System.out.println(s.name); //输出 李四
        s.doTest();  //输出 张三(子类没有该方法,父类该方法输出父类名字)
    }
}

测试类2:子类重写属性方法后,使用的是子类的属性

java 复制代码
//子类
public class SubTest2 extends Test {
	public String name = "李四";
	public void doTest() {
		System.out.println("son:"+name);
	} 
}
java 复制代码
public class Main {
    public static void main(String[] args) {
    	SubTest2 s = new SubTest2();
    	System.out.println(s.name); // 输出 李四
    	s.doTest();// 输出 son:李四
    }
}

测试类3:子类对象定义为父类类型,输出父类属性,调用的是子类方法

java 复制代码
//子类
public class SubTest2 extends Test {
	public String name = "李四";
	public void doTest() {
		System.out.println("son:"+name);
	} 
}
java 复制代码
public class Main {
    public static void main(String[] args) {
    	Test s = new SubTest2();
    	System.out.println(s.name);  // 输出 张三
    	s.doTest();   // 输出 son:李四
    }
}

测试类4:子类对象强转父类类型,输出父类属性,调用的是子类方法

java 复制代码
//子类
public class SubTest2 extends Test {
	public String name = "李四";
	public void doTest() {
		System.out.println("son:"+name);
	} 
}
java 复制代码
public class Main {
    public static void main(String[] args) {
    	SubTest2 s = new SubTest2();
    	Test ss = (Test)s;
    	System.out.println(ss.name);  // 输出 张三
    	ss.doTest();  // 输出 son:李四
    }
}

4 方法重载

方法名(相同),参数(个数或类型)(不同),与返回值无关

java 复制代码
public class Test {

    public String fn(String str){ 
    }
    // 重载1,参数类型不同
    public String fn(int num) {
    }
    // 重载2,参数个数不同
    public String fn(int age, int num) {
    }

}

5 super关键字

注释:只可在子类内部使用,使子类可以使用父类原生方法与属性

(1) 调用父类构造器:super**([参数...]);**

(2) 调用父类属性:super**.属性;** // 获取与更改父类的属性,不影响子类同名属性

(3) 调用父类方法:super**.方法();** // 调用父类的方法,与子类是否重写无关

java 复制代码
// 父类
public class Test {
	private String str1 = "私有";
	String str2 = "默认";
	protected String str3 = "保护";
	public String str4 = "公开";
	
	private String fn1() { return str1; }
	String fn2() { return str2; }
	protected String fn3() { return str3; }
	public String fn4() { return str4; }
}
java 复制代码
// 子类
public class SubTest extends Test {

	protected String str3 = "保护(son)";
	public String str4 = "公开(son)";
	
	protected String fn3() { return str3; }
	public String fn4() { return str4; }
	
    // 调用父类构造器(默认不写也调用)
	public SubTest() {
		super();
	}
    // 调用父类方法
	public void test() {
		System.out.println(super.str3);  // 输出 父类 保护
		System.out.println(super.str4);  // 输出 父类 公开
		System.out.println(super.fn3());  // 输出 父类 保护
		System.out.println(super.fn4());  // 输出 父类 公开
	}
	public void testSub() {
		System.out.println(str3);  // 输出 子类 保护(son)
		System.out.println(str4);  // 输出 子类 公开(son)
		System.out.println(fn3());  // 输出 子类 保护(son)
		System.out.println(fn4());  // 输出 子类 公开(son)
	}
}

6 代码执行顺序

6.1 静态方法

// 初次调用:类名.静态方法()

1.类加载(静态变量初期化,只执行1次)

2.类加载(静态代码块,只执行1次)

3.静态方法执行

// 之后再调用:类名.静态方法()// 只重复执行3

**3.**静态方法执行

6.2 实例化对象

// 初次实例化:new 对象()

1.类加载(静态变量初期化,只执行1次)

2.类加载(静态代码块,只执行1次)

3.代码块(执行)

4.构造器(执行)

// 之后再实例化:new 对象()// 只重复执行3,4

3.代码块(执行)

4.构造器(执行)

6.3 子类静态方法

// 初次调用:子类.静态方法()

1.父类加载(静态变量初期化,只执行1次)

2.父类加载(静态代码块,只执行1次)

3.子类加载(静态变量初期化,只执行1次)

4.子类加载(静态代码块,只执行1次)

5.子类静态方法(执行)

// 之后再调用:子类.静态方法()// 只重复执行5

5.子类静态方法(执行)

6.4 子类实例化对象

// 初次调用:new 子类对象()

1.父类加载(静态变量初期化,只执行1次)

2.父类加载(静态代码块,只执行1次)

3.子类加载(静态变量初期化,只执行1次)

4.子类加载(静态代码块,只执行1次)

5.父类代码块(执行)

6.父类构造器(执行)

7.子类代码块(执行)

8.子类构造器(执行)

// 之后再调用:new 子类对象()// 只重复执行5,6,7,8

5.父类代码块(执行)

6.父类构造器(执行)

7.子类代码块(执行)

8.子类构造器(执行)

总结:1 只有初次类加载初始化静态变量,执行静态代码块。2 父类(变量,代码块,构造器)优先于子类执行。3 代码块优先于构造器执行。

相关推荐
Mr_Xuhhh2 小时前
项目-sqlite类的实现
java·jvm·sqlite
ホロHoro2 小时前
学习笔记:Javascript(5)——事件监听(用户交互)
javascript·笔记·学习
孫治AllenSun2 小时前
【Springboot】介绍启动类和启动过程
java·spring boot·后端
爱喝水的鱼丶2 小时前
SAP-MM:SAP核心组织单元:工厂(Plant)全面学习指南及配置图解
学习·sap·abap·配置·工厂·mm模块
励志不掉头发的内向程序员2 小时前
STL库——AVL树
开发语言·c++·学习
晨非辰4 小时前
#C语言——刷题攻略:牛客编程入门训练(十一):攻克 循环控制(三),轻松拿捏!
c语言·开发语言·经验分享·学习·visual studio
xiaoxiaoxiaolll5 小时前
期刊速递 | 《Light Sci. Appl.》超宽带光热电机理研究,推动碳纳米管传感器在制药质控中的实际应用
人工智能·学习
励志码农6 小时前
JavaWeb 30 天入门:第二十三天 —— 监听器(Listener)
java·开发语言·spring boot·学习·servlet