|
|
本帖最后由 pansong291 于 2019-3-29 16:59 编辑
上篇:41.内部类---面向对象
下篇:43.类的继承(二)---面向对象
注意:如果你的回复只是“感谢分享”、“辛苦了”之类的与教程内容无关的字眼,还请不要回复本帖,谢谢合作!!!
注意:如果你的回复只是“感谢分享”、“辛苦了”之类的与教程内容无关的字眼,还请不要回复本帖,谢谢合作!!!
注意:如果你的回复只是“感谢分享”、“辛苦了”之类的与教程内容无关的字眼,还请不要回复本帖,谢谢合作!!!
面向对象的重要特色之一就是能够使用以前建造的类的方法和属性。通过简单的程序代
码来建造功能强大的类,会节省很多编程时间,而且更为重要的是,这样做可以减少代码出
错的机会。类的继承讲的就是这方面的问题。
继承的特点
我们还是通过一个实际应用问题,来引出类的继承这个问题的讲解。
我们常常在编程中遇到下面的情况:
public class Person
{
public String name;
public int age;
public String getInfo() {...}
}
public class Student
{
public String name;
public int age;
public String school;
public String getInfo() {...}
public String study() {...}
}
在上面的程序中,我们先定义了一个 Person 类来处理个人信息,接着又定义一个
Student 类来处理学生信息,结果发现 Student 类中包含了 Person 类的所有属性和方法。
针对这种情况,Java 为我们引入了继承这个概念,我们只要表明类 Student 继承了类
Person 的所有属性与方法,我们就不用在类 Student 中重复书写类 Person 中的代码了,更
确切的说是简化了类的定义。我们是通过 extends 关键字来表明类 Student 具有类 Person
的所有属性与方法,如果让 Student 类来继承 Person 类,Person 类里面的所有可继承的属
性和方法(后面我们会讲到什么是可继承的,什么是受限制的),都可以在 Student 类里面
使用了,也就是说 Student 这个类继承了 Person 类,拥有了 Person 类所有的特性,除此之
外还有一些自己的特性,如:学生有学校名和学习的动作。因此,我们就说 Person 是 Student
的父类(也叫基类或超类),Student 是 Person 的子类。例如上面的两个类,我们就可以简
写成下面的代码:
public class Person
{
public String name;
public int age;
public String getInfo() {...}
}
public class Student extends Person
{
public String school;
public String study() {...}
}
完整代码如下:
程序清单:Student.java
class Person
{
public String name;
public int age;
public Person(String name,int age)
{
this.name=name;
this.age=age;
}
public Person() //如果你不写这个构造函数,看看对类 Student 有什么影响。
{
}
public void getInfo()
{
System.out.println(name);
System.out.println(age);
}
}
class Student extends Person
{
public void study()
{
System.out.println("Studding");
}
public static void main(String[] args)
{
Person p=new Person();
p.name="person";
p.age=30;
p.getInfo();
Student s=new Student();
s.name="student";
s.age=16;
s.getInfo();
s.study();
}
}
要在以前的类上构造新类,必须要在新类的声明中扩展以前的类。通过扩展一个超类,
你可以得到这个类的一个拷贝,并可以在这个基础上添加新的属性和方法。如果你对这个新
类并不做什么添加工作,那么它的工作情况会与超类完全相同。新类中会含有超类所声明或
继承的所有属性和方法。在类的继承中,有这样的一些细节问题:
1).通过继承可以简化类的定义,我们已经在上面的例子中了解到了。
2).Java 只支持单继承,不允许多重继承。在 Java 中,一个子类只能有一个父类,不
允许一个类直接继承多个类,但一个类可以被多个类继承,如类 X 不可能既继承类 Y 又继承
类 Z。
3).可以有多层继承,即一个类可以继承某一个类的子类,如类 B 继承了类 A,类 C 又
可以继承类 B,那么类 C 也间接继承了类 A。这种应用如下所示:
class A
{}
class B extends A
{}
class C extends B
{}
4).子类继承父类所有的成员变量和成员方法,但不继承父类的构造方法。在子类的构
造方法中可使用语句 super(参数列表) 调用父类的构造方法。如:我们为 Student 类增加
一个构造方法,在这个构造方法中我们用 super 明确指定调用父类的某个构造方法。
class Student extends Person
{
public Student(String name,int age,String school)
{
super(name,age);
this.school=school;
}
}
5).如果子类的构造方法中没有显式地调用父类构造方法,也没有使用 this 关键字调用
重载的其它构造方法,则在产生子类的实例对象时,系统默认调用父类无参数的构造方法。
也就是,在下面的类 B 中定义的构造方法中,写不写 super()语句效果是一样的。
public class B extends A
{
public B()
{
super();//有没有这一句,效果都是一样的。
}
}
如果子类构造方法中没有显式地调用父类构造方法,而父类中又没有无参数的构造方法
(需要再次说明的是,如果父类没有显式的定义任何构造方法,系统将自动提供一个默认的
没有参数的构造方法,这还是等于父类中有无参数的构造方法的),则编译出错。读者将前
面的 Person 类中的无参数的构造方法注释掉,重新编译 Student 类,就能够看到这个错误
效果了。所以,我们在定义类时,只要定义了有参数的构造方法,通常都还需要定义一个无
参数的构造方法。
子类对象的实例化过程
对于许多 Java 老手来说,子类对象的实例化过程也不见得非常清楚,你可能并不需要
完全了解子类对象的实例化过程,但了解后还是有好处的。
对象中的成员变量的初始化是按下述步骤进行的:
1).分配成员变量的存储空间并进行默认的初始化,就是用 new 关键字产生对象后,对
类中的成员变量进行初始化赋值。
2).绑定构造方法参数,就是 new Person(实际参数列表)中所传递进的参数赋值给构
造方法中的形式参数变量。
3).如有 this()调用,则调用相应的重载构造方法(被调用的重载构造方法又从步骤 2
开始执行这些流程),被调用的重载构造方法的执行流程结束后,回到当前构造方法,
当前构造方法直接跳转到步骤 6 执行。
4).显式或隐式追溯调用父类的构造方法(一直到 Object 类为止,Object 是所有 Java
类的最顶层父类,在本章后面部分有详细讲解),父类的构造方法又从步骤 2 开始对父
类执行这些流程,父类的构造方法的执行流程结束后,回到当前构造方法,当前构造方
法继续往下执行。
5).进行实例变量的显式初始化操作,也就是执行在定义成员变量时就对其进行赋值的
语句,如:
public Student extends Person
{
String school = "it315"; // 显式初始化
……
}
将 "it315" 赋值给 school 成员变量。
6).执行当前构造方法的方法体中的程序代码,如
public Student extends Person
{
public Student(String name,int age,String school)
{
super(name,age);
this.school=school;
}
}
这一步将执行 this.school=school; 这条语句,其中用到的 super()或 this()方法调
用语句已在前面的步骤中执行过,这里就不再执行了。注意区别刚才所说的 this()方法调
用语句与 this.school=school; 的区别,前者指调用其他的构造方法,后者是一个普通的赋
值语句。
为了便于读者直观地看到子类对象的实例化过程,我将上面的流程用图 4.1 进行了重复
描述。
回过头来想一想:
1).为什么 super(…)和 this(…)调用语句不能同时在一个构造函数中出现?
2).为什么 super(…)或 this(…)调用语句只能作为构造函数中的第一句出现?
对照对象初始化实例变量过程,我们就发现这两种情况都违背上面的过程,所以读者应
该明白上面两个问题的原因了。
上篇:41.内部类---面向对象
下篇:43.类的继承(二)---面向对象 |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
x
|