面向对象继承性的导入
在生活中,存在很多的继承现象。例:古代皇位采用的就是继承制,父亲死后,一般情况下,儿子可以继承父亲的皇位。还有一般的爵位,也可以在父亲死后,又儿子来继承。现在的财产也可以又儿女继承父母的财产。而在程序层面,多个类中都需要定义相同的成员(属性、方法),如果在这多个类中都显示的去定义一遍,显然不太合适 ==> 程序代码的复用性较差。
我们考虑将这些共同的成员抽取定义到一个第三方的共性类中,让这多个类都去继承该共性类,
则共性类内部的成员这多个类就都可以使用了。这就是所谓的继承。
继承性的框架
搭建场景:
class A{}
class B extends A{}
描述关系:
A类:父类型、基类、超类、superclass
B类:子类型、派生类、subclass
继承性的体系结构图
食物
水果 水产品 豆类
苹果 香蕉 西瓜 鱼 虾 蟹 黄豆 红豆 黑豆
通过上述的简单示意图,我们可以得知:
越往上层/偏顶部的类:越模糊、越共性、越抽象
越往下层/偏底部的类:越清晰、越具体、越独立
继承性代码示例
//生物类 间接父类
class Creature{
//方法
public void breath(){
System.out.println("呼吸");
}
}
//人类 直接父类
class Person extends Creature{
//属性
String name;
int age;
//方法
public void eat(){
System.out.println("吃饭");
}
public void sleep(){
System.out.println("睡觉");
}
}
//学生类 子类
class Student extends Person{
//属性
int stu_id;
//方法
public void study(){
System.out.println("好好学习");
}
}
//教师类 子类
class Teacher extends Person{
//属性
int tea_id;
//方法
public void teach(){
System.out.println("认真教学");
}
}
public class TestExtends_1 {
public static void main(String[] args) {
//实例化学生对象
Student s = new Student();
//访问自己的属性
s.stu_id = 1;
//访问直接父类的属性
s.name = "张三";
s.age = 18;
//访问自己的方法
s.study();
//访问直接父类的方法
s.eat();
s.sleep();
//访问间接父类的方法
s.breath();
}
}
运行结果:

注意事项:
1).对于Java语言而言,类和类之间只能满足单一继承 ==> 一个类只能有一个直接父类
2).对于Java语言而言,类和类之间可以满足多重继承 ==> 一个类在有直接父类的同时还可以有间接父类
3).对于Java语言而言,类可以派生多个子类
4).由于类和类之间只能满足单一继承,存在一定的局限性;
所以Java设计者提出了接口这种技术,去解决上述的局限性问题,
类和接口之间可以多实现 ==> 一个类可以同时实现多个接口
5).语法层面:只要类和类之间定义使用了extends关键字,就可以发生继承关系 ==> final修饰的类除外
使用层面:类和类之间必须满足生活的逻辑和常态,必须具备一层"是"的关系,不能为了继承而继承。
super关键字
作用:
1.子类构造方法内部调用父类构造
格式:super(...)
参考代码:
//人类 直接父类
class Person{
//属性
String name;
int age;
private double money = 1000000.0;
//getter方法
public double getMoney(){
return money;
}
//方法
public void eay(){
System.out.println("吃饭");
}
public void sleep(){
System.out.println("睡觉");
}
//构造方法
public Person(){
}
public Person(String name,int age){
this.name = name;
this.age = age;
}
}
//学生类 子类
class Student extends Person{
//属性
int stu_id;
//方法
public void study(){
System.out.println("好好学习");
}
public void printInfo(){
System.out.println("学号:" + stu_id+",姓名:"+name+",年龄:"+age+ ",财富:" + getMoney());
}
//构造方法
public Student(String name,int age,int stu_id){
super(name,age);
this.stu_id = stu_id;
}
}
public class TestExtends_2 {
public static void main(String[] args) {
//创建学生对象
Student s1 = new Student("张三",18,1);
//打印信息
s1.printInfo();
}
}
运行结果:

注意事項:
1).父类私有化的成员(属性、方法),子类通过继承关系的搭建也是可以获取到的,但是由于封装性的缘故不可以直接访问调用。
2).实例化类的对象,都会一路调用super(...)的构造方法直到Object()构造方法为止,
中间有任何环节出现问题,导致到不了Object(),则该实例化操作一定以失败而告终。
3).类中显示定义带参构造方法的同时建议大家务必保留一个空参构造方法,原因如下:
①.有新的子类去继承该类,不会由于丢失super()而报错
②.方法使用反射技术去创建对象
4).子类构造方法内部调用父类构造,必须在首行位置进行调用。即对super的调用必须是构造器中的第一个语句。
2.调用父类非静态属性
子父类中都定义了相同名字的非静态属性,在子类方法内部去调用该非静态属性,
默认情况下调用的是子类中的该非静态属性(就近原则),如果想要去调用父类中的该非静态属性,
需要显示的定义super.非静态属性名的方式来实现
格式:super.非静态属性;
参考代码
class Fu
{
int a = 10;
static int b = 20;
private int c = 30;
public int getC(){
return c;
}
}
class Zi extends Fu
{
int a = 100;
static int b= 200;
public void test(){
int a = 1000;
System.out.println("a=" + a); //就近原则 a=1000
System.out.println("Zi类成员变量a=" + this.a); //a=100
System.out.println("Fu类成员变量a=" + super.a); //a=10
System.out.println("Zi类静态属性b=" + Zi.b); //b=200
System.out.println("Fu类静态属性b=" + Fu.b); //b=20
System.out.println("Fu类私有属性c=" + getC());
}
}
class TestExtends_3
{
public static void main(String[] args)
{
new Zi().test();
}
}
运行结果:

3.调用父类非静态方法
子父类中都定义了相同名字的非静态方法,在子类别的方法内部调用该非静态方法,
默认情况下调用执行的是子类中的该非静态方法(就近原则),如果想要访问调用父类中的该非静态方法,
需要显示的定义super.非静态方法名(...)来实现
格式:super.非静态方法名(...);
参考代码:
class Father
{
public void func(){
System.out.println("Father...func");
}
}
class Son extends Father
{
public void func(){
System.out.println("Son...func");
}
public void test(){
super.func();
}
}
class TestExtends_4
{
public static void main(String[] args)
{
new Son().test();
}
}
运行结果:


1280

被折叠的 条评论
为什么被折叠?



