Java基础(十六)

继承的定义与使用

面向对象的第二大特征就是继承性,继承性的主要特点:可以扩充已有类的功能。

1:继承问题的引出

良好的代码指的是结构合理,适合于维护,可用性高,可重用性高;

例如:要定义两个类:人类,学生类;两者都有姓名和年龄属性;发现有一些重复的代码出现在程序之中;进一步思考:学生是一个人,人是一个更加广泛的定义范畴,而学生是一个相对狭小的定义范畴,从另一个角度,学生之中应该包含人所有的特点。

这个时候想要进行代码的重用,就必须使用继承的概念来解决问题;

所谓继承的本质:在已有 类的功能上继续进行功能的扩充。

2:继承的实现

class 子类 extends 父类 { };

有时候把子类称为派生类,把父类称为超类(superClass)

class Person {
	private String name ;
	private int age ;
	public void setName(String name) {
		this.name = name ;
	}
	public void setAge(int age) {
		this.age = age ;
	}
	public String getName() {
		return this.name ;
	}
	public int getAge() {
		return this.age ;
	}
}
class Student extends Person {	// Student是子类
	// 在子类之中不定义任何的功能
}
public class JavaDemo {
	public static void main(String args[]) {
		Student stu = new Student() ;
		stu.setName("林大强") ;	 // 父类定义
		stu.setAge(38) ; // 父类定义
		System.out.println("姓名:" + stu.getName() + "、年龄:" + stu.getAge()) ;
	}
} 

由于此时存在有继承关系,子类即便没有定义任何的操作,也可以直接通过父类继承而来的方法实现相应的功能;内存关系图如下:

在这里插入图片描述

继承的主要目的:

子类可以重用父类中的结构,并且可以实现功能的扩充;

子类可以定义更多的内容,并且描述的范围更小。(代码如下)

class Person {
	private String name ;
	private int age ;
	public void setName(String name) {
		this.name = name ;
	}
	public void setAge(int age) {
		this.age = age ;
	}
	public String getName() {
		return this.name ;
	}
	public int getAge() {
		return this.age ;
	}
}
class Student extends Person {	// Student是子类
	private String school ; // 子类扩充的属性
	public void setSchool(String school) {
		this.school = school ;
	}
	public String getSchool() {
		return this.school ;
	}
}
public class JavaDemo {
	public static void main(String args[]) {
		Student stu = new Student() ;
		stu.setName("林大强") ;	 // 父类定义
		stu.setAge(38) ; // 父类定义
		stu.setSchool("家里蹲大学") ;
		System.out.println("姓名:" + stu.getName() + "、年龄:" + stu.getAge() + "、学校:" + stu.getSchool()) ;
	}
} 

观察内存关系:出现了两个范围的属性。

在这里插入图片描述

3:子类对象实例化流程

一旦程序有了继承关系,对于子类对象的实例化定义是有要求的:在进行子类对象实例化的时候首先要实例化好父类对象,观察如下代码。

class Person {
	public Person() {
		System.out.println("【Person父类】一个新的Person父类实例化对象产生了。") ;
	}
}
class Student extends Person {	// Student是子类
	public Student() {	// 构造方法
		System.out.println("【Student子类】一个新的Student实例化对象产生了。") ;
	}
}
public class JavaDemo {
	public static void main(String args[]) {
		new Student() ; // 实例化子类对象
	}
} 
//运行结果:
【Person父类】一个新的Person父类实例化对象产生了。
【Student子类】一个新的Student实例化对象产生了。

现在即使没有进行父类对象实例化,也会由系统自动调用父类的构造方法(实现父类对象);默认情况下的子类对象实例化流程里边会自动实现实例化父类对象;实际上这个时候就相当于子类的构造方法里边隐含了一个”super()“,代码如下。

class Person {
	public Person() {
		System.out.println("【Person父类】一个新的Person父类实例化对象产生了。") ;
	}
}
class Student extends Person {	// Student是子类

	public Student() {	// 构造方法
		super;//写不写次语句效果一样
		System.out.println("【Student子类】一个新的Student实例化对象产生了。") ;
	}
}
public class JavaDemo {
	public static void main(String args[]) {
		new Student() ; // 实例化子类对象
	}
} ```


super()表示的就是子类构造调用父类构造的语句,该语句允许放在子类构造方法的首行;

在默认情况下,子类只会调用父类的无参构造方法,所以写于不写“super()”区别不大,如果父类里面没有提高无参构造就必须利用super()明确调用有参构造(代码如下)。

class Person {
private String name ;
private int age ;
public Person(String name,int age) {
this.name = name ;
this.age = age ;
}
}
class Student extends Person { // Student是子类
private String school ;
public Student(String name,int age,String school) { // 构造方法
super(name,age) ; // 明确调父类构造
this.school = school ;
}
}
public class JavaDemo {
public static void main(String args[]) {
new Student(“林小强”,48,“北京大学”) ; // 实例化子类对象
}
}



**结论**


在实例化子类对象的同时一定会是俩胡父类对象,目的是为了所有的属性可以进行空间分配。


super和this都可以调用构造方法,super是由子类调用父类构造,而this 是调用本类构造;两者必须放在构造方法的首行,所以两个语句不允许同时出现。


*4:继承的相关限制*

a:Java之中不允许多重继承,只允许多层继承。

class A{ }
class B extends A{ }
class C extends B{ }



继承的目的是扩展已有类的功能,理论上层次不应该超过三层。

b:在进行继承关系定义的时候,实际上子类可以继承父类中所有的操作结构。但是对于私有操作属于隐式继承,而非所有的非私有操作属于显示继承。


class Person {
private String name ;
public void setName(String name) {
this.name = name ;
}
public String getName() {
return this.name ;
}
}
class Student extends Person {
public Student(String name) {
setName(name) ; // 设置name属性内容
}
public void fun() {
// System.out.println(name) ; // 直接访问不可能,因为私有的
System.out.println(getName()) ; // 间接访问
}
}
public class JavaDemo {
public static void main(String args[]) {
Student stu = new Student(“林中强”) ;
stu.fun() ;
}
}
//继承一旦发生了,所有的操作就都可以被子类使用了,此类至少会维持父类的现有功能。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值