本章目标
•对象数组(补充)
•对象数组(补充)
•理解什么是继承
•在Java中实现继承,extends关键字
•四种访问控制权限
>public
>protected
>private
>缺省
•继承中的构造方法
•super关键字
对象数组
•在Java中不但可以声明由原始数据组成的数组,还可以声明由对象组成的数组;
声明对象数组的方式如:
//假设已经定义了一个Student类
/*声明由5个Student对象组成的数组*/
Student[] stdAry = new Student[5];
对象数组==引用数组
对象数组示例:
/*对象数组示例,假设已经定义了Student类*/
public static void main(String[] args)
{
/*创建包含有5个Student引用的数组*/
Student[] stdAry = new Student[5];
/*逐一为每个引用创建对象实例*/
stdAry[0] = new Student("张三", 18);
stdAry[1] = new Student("李四", 20);
stdAry[2] = new Student("王五", 24);
stdAry[3] = new Student("郑六", 21);
stdAry[4] = new Student("田七", 19);
for (int i = 0; i < stdAry.length; i++)
{
stdAry[i].display();
}
}
对象数组的存放形式
继承的概念
•在现实生活中的继承,可以理解为儿子继承了父亲的财产,即财产重用;
•面向对象程序设计中的继承,则是代码重用;
•继承是利用现有的类创建新类的过程,现有的类称作基类(或父类),创建的新类称作派生类(子类)。
继承的概念(续)
继承的概念(续)
•最高层是最普遍的、最一般的情况,往下每一层都比上一层更具体,并包含有高层的特征,通过这样的层次结构使下层的类能自动享用上层类的特点和性质;
•继承其实就是自动地共享基类中非私有的成员属性和非私有的成员方法的机制。
在Java中实现继承
•在Java中实现继承需要使用到extends关键字;java只支持单继承
•实现继承的一般语法是:
[访问修饰符] class 派生类名 extends 基类名 {
成员列表
}
•如:
实现继承示例:
class Student extends Person
{
……
}
class Person { //定义人类
public String mName; //姓名
public int mAge; //年龄
public void dining() { System.out.println("吃饱了..."); } //吃饭的方法
}
class Student extends Person { //学生类继承于人类
public float mGrade; //成绩
public void examination() { System.out.println("考试及格了..."); } //考试的方法
}
class Teacher extends Person { //教师类继承于人类
public float mSalary; //薪水
public void prelection() { System.out.println("上课很累..."); } //上课的方法
}
public class InheritanceDemo { //该类用于容纳main方法
public static void main(String[] args) {
Student std = new Student(); //实例化学生对象
std.mName = "张三"; std.mAge = 18; //为姓名和年龄赋值,访问的是父类中的成员
std.dining(); //调用吃饭的方法,访问的是父类中的成员
std.examination(); //调用考试方法,访问的是子类中的成员
Teacher tea = new Teacher(); //实例化教师对象
tea.mName = "谭浩强"; tea.mAge = 65;
tea.dining();
tea.prelection();
}
}
当今软件设计的特征:
>软件规模越来越大;
>软件设计者越来越多;
>软件设计分工越来越细。
•引入继承,实现了代码重用;
•引入继承,实现了递增式的程序设计。
继承的作用(续)
•继承是能自动传播代码和重用代码的有力工具;
•继承能够在某些比较一般的类的基础上建造、建立和扩充新类;
•能减少代码和数据的重复冗余度,并通过增强一致性来减少模块间的接口和界面,从而增强了程序的可维护性;
•能清晰地体现出类与类之间的层次结构关系。
与继承有关的注意事项
类成员的访问控制权限
访问修饰符
访问控制权限
课堂练习
1.
2.
3.
类的访问权限
继承中的构造方法
继承中的构造方法示例:
•能清晰地体现出类与类之间的层次结构关系。
与继承有关的注意事项
•
java继承是单方向的,即子类可以继承和访问父类中的成员,但父类则无法访问子类中的成员;
•在Java中只允许单一继承方式,即一个派生类只能继承于一个基类,而不能像C++中派生类继承于多个基类的多重继承方式。
类成员的访问控制权限
•信息隐藏是面向对象程序设计的重要特点之一,它可以:
>防止类的使用者意外损坏数据;
>对任何实现细节所作的修改不会影响到使用该类的其它代码;
>使类更易于使用。
•在Java中实现信息隐藏的是访问控制权限机制;
•访问控制权限包括4个访问修饰符:public、protected、private和缺省;
•可以使用上述访问修饰符修饰类的成员。
访问修饰符
访问控制权限
课堂练习
1.
2.
类的访问权限
•还可以在定义类时为类添加访问修饰符,对类进行访问权限控制;
•
对类使用的访问修饰符只有public和缺省两种;
•被public修饰的类可以从任何地方访问,不受限制;
•不加访问修饰符,缺省修饰的类只能从本包中访问,不同包则无法访问到;
•但要注意的是:在一个源文件中只能有一个被public修饰的类,并且文件名必须与public的类同名;
•
如果要定义多个public的类,则必须分别写在不同的源文件中,一个源文件只写一个类是良好的编程习惯。
继承中的构造方法
•
父类中的构造方法不能被子类继承,即便它是public的;
•父类的构造方法负责初始化属于它的成员变量,而子类的构造方法则只需考虑属于自己的成员变量,不必去关注父类的情况。
继承中的构造方法示例:
class ParentClass { //定义父类
public ParentClass() { //构造方法
System.out.println("这是父类的构造方法。");
}
}
class ChildClass extends ParentClass { //子类继承于父类
public ChildClass() { //构造方法
System.out.println("这是子类的构造方法。");
}
}
public class ConstructorTest { //该类用于容纳main方法
public static void main(String[] args) {
ChildClass cc = new ChildClass(); //实例化子类对象
}
}
构造方法的执行顺序
•当实例化子类的对象时,必须先执行父类的构造方法,然后再执行子类的构造方法;
•如果父类还有更上级的父类,就先调用最高父类的构造方法,再逐个依次将所有继承关系的父类构造方法全部执行;
•如果父类的构造方法执行失败,那么子类的对象也将无法实例化。
案例:
class Point { //定义"点"类
//x轴坐标和y轴坐标,由于准备用于继承,故修饰为protected
protected float mX, mY;
public Point(float x, float y) { //构造方法
mX = x;
mY = y;
}
}
class Circle extends Point { //定义"圆"类继承于"点"类
protected float mRadius; //半径
public Circle(float r) { //构造方法
mRadius = r;
}
}
public class Demo {
public static void main(String[] args) {
Circle c = new Circle(2.5f); //实例化"圆"类对象
}
}
//本例将报错
案例分析:
•在实例化Circle类对象时,虚拟机一定会先调用其父类(Point类)的构造方法;
•Point类的构造方法需要两个参数来初始化其成员,但此时并没有获得这两个参数,造成Point类的构造方法无法执行;
•父类的构造方法执行失败从而导致子类(Circle类)的对象也无法创建;
•问题的关键是:在实例化子类对象时,如何将参数传递给父类的构造方法?这将使用到super关键字。
super关键字的第一种用途
•在Java中,super关键字有两个主要用途;
•第一种用途是:在子类的构造方法中,super关键字可以显式地调用父类的构造方法,用于将参数传递给它;
•其一般语法是:
super(实际参数);
•需要注意的是:该语句必须是子类构造方法的第一条语句。
super关键字示例1
class Point //定义"点"类
{
protected float mX, mY; //x轴坐标和y轴坐标
public Point(float x, float y) //构造方法
{
mX = x;
mY = y;
}
……
}
class Circle extends Point //定义"圆"类继承于"点"类
{
protected float mRadius; //半径
public Circle(float x, float y, float r) //构造方法
{
super(x, y); //显式调用父类构造方法,必须是第一条语句
mRadius = r;
}
……
}
super关键字的第二种用途
•如果父类和子类中有同名成员,在子类中默认访问是属于自己的那一个成员;
•super关键字可以明确地指定要访问父类中的成员;
•其一般语法是:
super.成员名;
•前提条件是:父类中的该成员不是private的。
super关键字示例2
//定义父类
class SuperClass
{
protected int num;//①
……
}
//定义子类,继承于父类
class SubClass extends SuperClass
{
protected int num; //子类中有与父类成员同名的成员②
public void fun()
{
num = 10; //默认访问自己的成员②
super.num = 20; //指定访问父类的成员①
}
……
}
作业
•编写一个程序,用于创建一个名为Employee的父类和两个名为Manager和Director的子类,Employee类中包含三个属性和一个方法,属性为name,basic和address,方法为show用于显示这些属性的值。Manager类有一个称为department的附加属性。Director类有一个称为transportAllowance的附加属性。创建包含main方法的EmployeeTest类,在main方法创建Manager和Director类的对象,并调用show方法显示其详细信息。
>要求:
>所有类的属性通过构造方法初始化。
>name是名字、basic是基本底薪、address是地址、transportAllowance是津贴
作业效果