为y1,隐藏了父类Point 中的两个成员变量x 和y。子类执行自己的方法时,操作的是子类的变量,子类执行父类的方法时,操作的是父类的变量。在子类中要特别注意成员变量的命名,防止无意中隐藏了父类的关键成员变量,这有可能给程序带来麻烦。 5.了解成员方法的覆盖方式
(1)方法覆盖的定义与作用
通过继承子类可以继承父类中所有可以被子类访问的成员方法,但如果子类的方法与父类方法同名,则不能继承,此时称子类的方法覆盖了父类的方法,简称为方法覆盖(override)。方法覆盖为子类提供了修改父类成员方法的能力。例如,子类可以修改层层继承下来的Object 根类的toString 方法,让它输出一些更有用的信息。下面的程序显示了在子类Circle 中添加toString 方法,用来返回圆半径和圆面积信息。
(2)编写覆盖Object 类toString 方法的程序文件Demo3_6.java,源代码如下。 class Circle {
private int radius; Circle(int r) { setRadius(r); }
public void setRadius(int r) { radius=r; }
public int getRadius() { return radius; }
public double area() {
return 3.14159*radius*radius; }
public String toString() {
return \圆半径:\圆面积:\} }
public class Demo3_6{
public static void main(String args[]) { Circle c=new Circle(10);
System.out.println(\} }
(3)编译并运行程序
(4)程序结构分析。
程序添加了toString 方法并修改了它的返回值。由于toString 和继承下来的Object 类的方法名相同、返回值类型相同,因此覆盖了超类Object 中的toString 方法。
方法覆盖时要特别注意:
用来覆盖的子类方法应和被覆盖的父类方法保持同名、相同的返回值类型,以及相同的参数个数和参数类型。
6.This、super 和super()的使用
(1)程序功能:说明this、super 和super()的用法。程序首先定义Point(点)类,然后创建点的子类Line(线)。最后通过Demo3_7类输出线段的长度。
程序中通过super(a,b)调用父类Point 的构造方法为父类的x 和y 赋值。在子类Line 的setLine方法中,因为参数名和成员变量名相同,为给成员变量赋值,使用this 引用,告诉编译器是为当前类的成员变量赋值。在length 和toString 方法中使用父类成员变量时,使用super 引用,告诉编译器使用的是父类的成员变量。
(2)使用this、 super 和super()的程序文件Demo3_7.java,源代码如下。 class Point {
protected int x, y; Point(int a, int b) { setPoint(a, b); }
public void setPoint(int a, int b) { x=a; y=b; } }
class Line extends Point { protected int x, y; Line(int a, int b) { super(a, b); setLine(a, b); }
public void setLine(int x, int y) { this.x=x+x; this.y=y+y; }
public double length() {
int x1=super.x, y1=super.y, x2=this.x, y2=this.y;
return Math.sqrt((x2-x1) * (x2-x1) + (y2-y1) * (y2-y1)); }
public String toString() {
return \直线端点:[\x + \直线长度:\} }
public class Demo3_7{
public static void main(String args[]) { Line line=new Line(50, 50);
System.out.println(\
} }
(3)编译并运行程序。
四、类的多态性练习
1. 理解类的多态性
类的继承发生在多个类之间,而类的多态只发生在同一个类上。在一个类中,可以定义多个同名的方法,只要确定它们的参数个数和类型不同。这种现象称为类的多态。
多态使程序简洁,为程序员带来很大便利。在OOP 中,当程序要实现多个相近的功能时,就给相应的方法起一个共同的名字,用不同的参数代表不同的功能。这样,在使用方法时不论传递什么参数,只要能被程序识别就可以得到确定的结果。
类的多态性体现在方法的重载(overload)上,包括成员方法和构造方法的重载。 2. 方法的重载
方法的重载是指对同名方法的不同使用方式。 3.构造方法的重载
构造方法的名称和类同名,没有返回类型。尽管构造方法看起来和一般的成员方法没有差别,但它不是方法,也不是类的成员。因此,构造方法不能直接调用,只能由new 操作符调用。
构造方法对于类是十分重要的,对象的初始化任务要靠构造方法来完成。 重载构造方法的目的是提供多种初始化对象的能力,使程序员可以根据实际需要选用合适的构造方法来初始化对象。
(1) 编写构造方法RunDemo 的重载程序文件Demo3_8.java,源代码如下。
class RunDemo {
private String userName, password; RunDemo() {
System.out.println(\全部为空!\}
RunDemo(String name) { userName=name; }
RunDemo(String name, String pwd) { this(name); password=pwd; check(); }
void check() { String s=null;
if (userName!=null) s=\用户名:\
else
s=\用户名不能为空!\if (password!=\s=s+\口令无效!\else
s=s+\口令:********\System.out.println(s); } }
public class Demo3_7{
public static void main(String[] args) { new RunDemo();
new RunDemo(\刘新宇\
new RunDemo(null,\邵丽萍\new RunDemo(\张驰\} }
(2)编译并运行程序。
(3)三个构造方法,其中
第一个无参构造方法RunDemo() 的实际作用是对成员变量赋缺省初值,由于userName和password都是String 类,所以它们的缺省初值为null。
第二个构造方法RunDemo(String) 只有一个参数,用来对成员变量userName 赋初值。 第三个构造方法RunDemo(String, String) 有两个参数,并有更多的内容,首先调用this(name),其实际作用就是调用当前类的构造方法RunDemo(String name);然后对成员变量password 赋值;最后调用check 方法来检查userName 和password,类似于一般程序的口令验证。重载构造方法的执行由对象根据实际参数的个数、类型和顺序确定。
体会:
通过本章的实验,我知道了类由变量和方法两部分组成,静态变量/方法与实例变量/方法的区别,类的静态变量可以直接引用,而非静态变量则不行,静态方法只能使用静态变量,不能使用实例变量,子类可以继承父类中所有可以被子类访问的成员方法,但如果子类的方法与父类方法同名,则不能继承。多态性体现在方法重载实现的静态多态性和方法覆盖实现的动态多态性两个方面。