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 代码块优先于构造器执行。

相关推荐
唐青枫3 小时前
Java JDBC 实战指南:从 Connection 到事务和连接池
java
一个做软件开发的牛马4 小时前
MyBatis-Plus 从零实战:完整搭建可运行 Demo,BaseMapper 零 SQL、Wrapper 条件构造、分页插件与代码生成器详解
java·后端
用户3721574261354 小时前
Java 处理 PDF 图片:提取 PDF 中的图片,并压缩 PDF 图片体积
java
用户3721574261354 小时前
Java 打印 Word 文档:从基础打印到高级设置
java
用户35218024547520 小时前
当 Prompt 学会"热更新":Spring Boot × Nacos3 AI 实战
java·spring boot·ai编程
东坡白菜1 天前
破局全栈:一个前端开发的Java入门实战记录(1)
java·全栈
唐青枫1 天前
Java Tomcat 实战指南:从 Servlet 容器到 Spring Boot 部署
java
wsaaaqqq1 天前
roudan:自由选择实体、灵活操作数据、快速写入数据库的 Java 框架
java
plainGeekDev1 天前
null 判断 → Kotlin 可空类型
android·java·kotlin
糖拌西瓜皮1 天前
Java开发者视角:深入理解Node.js异步编程模型
java·后端·node.js