1、JAVA语言程序设计,第七讲 对象和类(续),类的继承 (extends) 抽象类 (abstract class) 静态变量的初始化 接口 (interface),类的继承,父类与子类的关系 (extends) 基本内容 子类可调用父类的非私有方法和变量,子类可增加父类中没有的方法和变量 子类可重新定义父类的静态/实例变量 子类可重新定义父类的静态/实例方法 继承中的构造方法 类成员访问修饰符与继承的关系,类的继承,子类可调用父类的非私有方法和变量 子类可增加父类中没有的方法和变量,class Vehicle String brand;void setB(String s) brand =
2、s; void showB() System.out.println(brand); ,class Bus extends Vehicle int gas;void setG(int g) gas = g; void showG() System.out.println(gas); ,Bus b = new Bus(); b.setB(“audi”); /* b.setG(100); b.showB(); /* b.showG();,子类继承父类的方法和变量, 则这些方法和变量就属于子类, 则子类对象对这些方法和变量 的调用是显而易见的,类的继承,子类可重新定义父类中已有的变量 父类中同名的变
3、量无效(隐藏) 通过“super.变量名” 和父类名.变量名(static变量)引用,class A int i=256, j =64;static int k = 32;final float e = 2.718f; ,class B extends A public char j=x;final double k =5;static int e =321;void show() System.out.println(i + “ “ + j + “ “ + k + “ “ + e); void showA() System.out.println(super.j + “ “ + A.k +
4、“ “ + super.e); ,B b = new B(); b.show(); b.showA();,256 x 5.0 321 64 32 2.718,this.变量名 this.方法名 this()super.变量名 super.方法名 super(),super ? 当前对象/当前对象的父对象/其他,继承中的super对象,类的继承,父类,子类,调用父类的 变量和方法,调用子类的 变量和方法,3. 父类对象与子类对象的转换,父类对象和子类对象的转化需要注意如下的原则 : (1) 子类对象可以被视为是其父类的一个对象 ; (2) 父类对象不能被当作是其某一个子类的对象 ; (3) 如果
5、一个方法的形式参数定义的是父类对象 , 那么调用这个方法时 , 可以使用子类对象作为实际参数 ; (4) 如果父类对象引用指向的实际是一个子类对象 ( 在以前的某个时候根据 (1) 把子类对象的引用赋值给这个父类对象的引用 ), 那么这个父类对象的引用可以用强制类型转换转化成子类对象的引用。,SuperClass sc=new SubClass();,sc,SuperClass,SubClass,SubClass sb=new SuperClass();,sb,SubClass,SuperClass,继承中的构造方法,类的继承,public class Cartoon extends Draw
6、ing Cartoon() System.out.println(“Cartoon Constructor“);public static void main(String args) Cartoon c = new Cartoon(); ,class Art Art() System.out.println(“Art Constructor“); ,class Drawing extends Art Drawing() System.out.println(“Drawing Constructor“); ,Art Constructor Drawing Constructor Cartoon
7、 Constructor,子类的构造方法 必须调用 父类的构造方法,class Drawing extends Art /*Drawing() System.out.println(“Drawing Constructor“);*/ ,Art Constructor Cartoon Constructor,public class Cartoon extends Drawing Cartoon() super();System.out.println(“Cartoon Constructor“);public static void main(String args) Cartoon c =
8、new Cartoon(); ,再谈继承中的构造方法,类的继承,public class Chess extends BoardGame Chess() super(3);System.out.println(“Cartoon Constructor“);public static void main(String args) Chess c = new Chess(); ,class Game Game(int i) System.out.println(“Game Constructor“); ,class BoardGame extends Game BoardGame(int i) s
9、uper(i);System.out.println(“BoardGame Constructor“); ,子类的构造方法 必须要对父类的 构造方法进行 调用, 不管以任何形式, 否则编译出错,再谈继承中的构造方法,类的继承,class A A (int i) ,class B extends A B (String s) ,B (String s) super(); ,类的继承,子类可重新定义父类中已有的静态变量(static),class Point static int x = 2; class TPoint extends Point static double x = 4.7;pub
10、lic static void main(String args) new TPoint().printX();void printX() System.out.println(x + “ “ + Point.x); ,4.7 2,类的继承,子类可重新定义父类中已有的实例变量,class Point int x = 2; class TPoint extends Point double x = 4.7;void printBoth() System.out.println(x + “ “ + super.x); public static void main(String args) TPo
11、int t = new TPoint();t.printBoth();System.out.println(t.x + “ “ + (Point)t).x); ,4.7 2 4.7 2,类的继承,再谈子类对父类变量的继承,import points.Point3d; class Point4d extends Point3d int w;public void move(int dx, int dy, int dz, int dw) x += dx; y += dy; z += dz; w += dw; ,package points; public class Point int x, y;
12、public void move(int dx, int dy) x += dx; y += dy; ,package points; public class Point3d extends Point int z;public void move(int dx, int dy, int dz) x += dx; y += dy; z += dz; ,目录结构 /points/Point.class /points/Point3d.class /Point4d.class,import points.Point3d; class Point4d extends Point3d int w;p
13、ublic void move(int dx, int dy, int dz, int dw) super.move(dx, dy, dz); w += dw; ,编译时报错: x, y, z仅在本包 中才能访问,继承与类成员的访问修饰符有关!,类的继承,类成员访问修饰符与继承的关系,class Point int x, y;private Point() reset(); Point(int x, int y) this.x = x; this.y = y; private void reset() this.x = 0; this.y = 0; ,class ColoredPoint ex
14、tends Point int color;void clear() reset(); ,class Test public static void main(String args) ColoredPoint c = new ColoredPoint(0, 0); c.reset(); ,An error occurs because ColoredPoint has no constructor declared with two integer parameters, as requested by the use in main. This illustrates the fact t
15、hat ColoredPoint does not inherit the constructors of its superclass Point.,Another error occurs because ColoredPoint declares no constructors, and therefore a default constructor for it is automatically created, and this default constructor is equivalent to: ColoredPoint() super(); which invokes th
16、e constructor, with no arguments, for the direct superclass of the class ColoredPoint. The error is that the constructor for Point that takes no arguments is private, and therefore is not accessible outside the class Point.,Two more errors occur because the method reset of class Point is private, an
17、d therefore is not inherited by class ColoredPoint.,类的继承,类成员访问修饰符与继承的关系 私有的(private)类成员不能被子类继承 公共的(public)和保护性的(protected)类成员能被子类继承,且子类和父类可以属于不同的包 无修饰的父类成员,仅在本包中才能被子类继承 构造函数不是类成员,所以不被继承,package points; public class Point public int x, y;protected int useCount = 0;static protected int totalUseCount =
18、 0;public void move(int dx, int dy) x += dx; y += dy; useCount+; totalUseCount+; ,import points.Point; class Test extends Point public void moveBack(int dx, int dy) x -= dx; y -= dy; useCount+; totalUseCount+; ,类的继承,例,class Position int x, y;Position(int px, int py) x=px; y=py;void show() System.out
19、.println(x+”,”+y); ,class Spot extends Position boolean display;Spot(int sx, int sy, boolean sf) super(sx, sy); display=sf;void change(int cx, int cy)x=cx; y=cy; ,class Box extends Spot int r; Box(int bx,int by, int br, boolean bf) super(bx,by,bf);r=br;void add(int da) r+=da;void red(int da) r-=da;v
20、oid show() System.out.print(“起点:”);super.show();System.out.print(“边长:”+r);if (display)System.out.println(“显示”);else System.out.println(“不显示”); ,Spot s = new Spot(100,100,false); s.show(); Box b=new Box(100,100,30,true); b.show(); b.change(200,300); b.add(50); b.show();,继承中类对象作为参数传递,类的继承,class Side v
21、oid display() System.out.println(“平面: ”); ,class Spot extends Side private int x, y;Spot(int u, int v) x=u; y=v; void display() System.out.println(x+“ “+y); ,class Line extends Side private int x1, y1, x2, y2; Line(int a1, int b1, int a2, int b2) x1=a1;y1=b1; x2=a2;y2=b2;void display() System.out.pr
22、intln(x1+“ “+y1);System.out.println(x2+“ “+y2) ,Spot s = new Spot(2, 3); Line l = new Line(1,2,3,4); display(s); display(l);,static void display(Side s) s.display(); ,Subclasses inherit those superclass members declared as public or protected. Subclasses inherit those superclass members declared wit
23、h no access specifier as long as the subclass is in the same package as the superclass. Subclasses dont inherit a superclasss member if the subclass declares a member with the same name. In the case of member variables, the member variable in the subclass hides the one in the superclass. In the case
24、 of methods, the method in the subclass overrides the one in the superclass.,小结,小结,类的继承 重写: 子类和父类的方法名、返回类型和参数相同,与重载(overload)的区别 如果是实例方法,则称为子类重写(overriding)父类的实例方法 如果是类方法,则称为子类隐藏父类的类方法(static) 实例方法不能重写静态方法 静态方法不能重写实例方法 final/private方法不能被重写或隐藏注: 实例变量可隐藏静态变量静态变量可隐藏实例变量,class Father public void set() s
25、tatic void get() ,class Son extends Father public void set() static void get() ,class Son extends Father public void get() static void set() ,类的继承,子类对象与父类对象 Classroom c = new MMClassroom(); (等价于) MMClassroom c1 = new MMClassroom(); Classroom c = c1; 子类对象可以被视为其父类的一个对象父类对象不能当作某一个子类对象,继承与组合,类的继承,class
26、Engine public void start() public void rev() public void stop() ,class Wheel public void inflate(int i) ,public class Car public Engine engine = new Engine();public Wheel wheel = new Wheel4;public Door left = new Door();public Door right = new Door();public Car() for (int i =0; i 4; i+) wheeli = new
27、 Wheel();public static void main(String args) Car car = new Car();car.left.window.rollup();car.wheel0.inflate(72); ,class Window public void rollup() public void rolldown() ,class Door public Window window = new Window();public void open()public void close() ,组合: 有一个 (has-a),继承: 是一个 (is-a),一个文件中定义多个
28、JAVA类,class Game Game(int i) System.out.println(“Game Constructor“); class BoardGame extends Game BoardGame(int i) super(i);System.out.println(“BoardGame Constructor“); public class Chess extends BoardGame Chess() super(3);System.out.println(“Cartoon Constructor“);public static void main(String args
29、) Chess c = new Chess(); ,仅保存为一个Chess.java文件 编译后,产生三个class文件,Game.class、BoardGame.class、Chess.class 执行,Chess.class 注:在类定义中只能将一个类定义为public,第七讲 对象和类(续),类的继承 (extends) 抽象类 (abstract class) 静态变量的初始化 接口 (interface),抽象类(abstract class),一个未完成的类 仅仅抽象类可以包含抽象方法(abstract methods) 抽象方法: 仅仅申明了方法,但未实现 有访问修饰词 返回值类
30、型 方法名 参数列表 无方法体,抽象类(abstract class),abstract class Point int x = 1, y = 1;void move(int dx, int dy) x += dx;y += dy;alert();abstract void alert(); ,abstract class ColoredPoint extends Point int color; ,class SimplePoint extends Point void alert() ,抽象方法: 有访问修饰词、 返回值类型、方法名和 参数列表,无方法体,抽象类(abstract clas
31、s),抽象类不能被实例化,例Point p = new Point(); 子类继承抽象类时,必须重写抽象方法,否则仍为抽象类,abstract class Point int x = 1, y = 1;void move(int dx, int dy) x += dx;y += dy;alert();abstract void alert(); ,abstract class ColoredPoint extends Point int color; ,class SimplePoint extends Point void alert() ,Point p = new SimplePoint
32、();,抽象类(abstract class),多态性,abstract class Graphics abstract void parameter();abstract void area(); ,class Rectangle extends Graphics double h, w;Rectangle (double u, double v) h = u; w = v;void parameter() System.out.println(h + “ “ + w);void area() System.out.println(h*w); ,Rectangle rec = new Rec
33、tangle(1.0, 2.0); Circle cir = new Circle(3.0, “Red”); Graphics g = rec, cir; for (int i = 0; i g.length; i+) gi.parameter();gi.area(); ,class Circle extends Graphics double r; String c;Circle (double u, String v) r = u; c = v;void parameter() System.out.println(r + “ “ + c); void area() System.out.
34、println(Math.PI*r*r); ,运行结果 1.0 2.0 2.0 3.0 Red 28.274333882308138,多态性(polymorphism),应用场合: 不同子类可以用 不同的方式实现同一共同 接口,该共同接口建立了 一个基本形式,第七讲 对象和类(续),类的继承 (extends) 抽象类 (abstract class) 静态变量的初始化 接口 (interface),static变量的初始化,class Smember static int i = 100;static boolean b = true;char c = t;public Smember()
35、public static void main(String args) Smember m1 = new Smember();Smember m2 = new Smember(); ,不论产生多少个对象, 属于类的静态变量只有一份, 即只占有一份存储空间,class Smember static int i; static boolean b;static i = 100;b = true;System.out.println(“In static block”);char c = t;public Smember() System.out.println(“In constructor”)
36、; public static void main(String args) Smember m1 = new Smember();Smember m2 = new Smember(); ,输出结果 In static block In constructor In constructor,设计模式的例子,class Singleton private static Singleton me = new Singleton();public static Singleton getSingleton() return me;private Singleton() public static v
37、oid main(String args) Singleton s1 = Singleton.getSingleton();Singleton s2 = Singleton.getSingleton();if (s1 = s2) System.out.println(“s1 is s2“);else System.out.println(“s1 is not s2“); ,该Singleton类只有一个实例, 即该Singleton类只能构造一 个对象,“Design Patterns: Elements of Reusable Object-Oriented Software” (设计模式)
38、 Erich Gamma、Richard Helm、Ralph Johnson、John Vlissides Addison-Wesley, 1995 这几位作者常被称为“四人组(Gang of Four)”, 而这本书也就被称为“四人组(或 GoF)”书 设计模式: 在一定的环境中解决某一问题的方案 23 种设计模式, 3大类 创建型模式(Creational pattern)规定了创建对象的方式,如Singleton模式、Factory Method模式 结构型模式(Structural pattern)规定了如何组织类和对象。这些模式涉及类如何相互继承或如何从其它类组合,如Adapter
39、、Proxy 和 Decorator 模式 行为模式(Behavioral pattern)规定了对象之间交互的方式。如Observer模式、Strategy和Template 模式 并发模式(Concurrency pattern)规定协调或顺序对共享资源访问的方式 MVC(Model/View/Controller, 模型/视图/控制器),设计模式的例子,public class Sequence private static Sequence instance;private static int counter;private Sequence() counter = 0; publi
40、c static synchronized Sequence getInstance() if (instance=null) instance = new Sequence();return instance;public static synchronized int getNext() return +counter; ,这个类不可以再有子类,因为构造方法是private Lazy instantiation (Lazy initialization),仅在需要的时候才实例化对象,private static Sequence instance = new Sequence();,第七讲
41、 对象和类(续),类的继承 (extends) 抽象类 (abstract class) 静态变量的初始化 接口 (interface),接口是对abstract类的进一步扩展 接口中的方法都是未实现的(类似于抽象方法),目的是在实现接口的类之间建立一种协议 接口中的变量都是常量 定义一个类符合某个或一组接口,利用implements,接口 (interface),An interface is a named collection of method definitions (without implementations). An interface can also declare co
42、nstants.,public interface 接口名 成员变量;方法声明;,class 类名 implements 接口1, 接口2 ,接口名修饰 public: 无任何访问限制 无修饰: 仅限于本包中 接口变量默认都是“public static final”public interface Months int JANUARY=1, FEBRUARY=2, MARCH=3,APRIL=4, MAY=5, JUNE=6, JULY=7,AUGUST=8, SEPTEMBER=9,OCTOBER=10,NOVEMBER=11,DECEMBER=12; ,接口 (interface),接口
43、 (interface),接口方法 无修饰 但在实现接口方法的类中,修饰符为public,interface Figure double half=0.5,pi=3.14159;void parameter();void area(); ,class Triangle implements Figure double b, h;Triangle (double u, double v) b = u; h = v;public void parameter() System.out.println(b + “ “ + h);public void area() System.out.printl
44、n(half*h*b); ,class Circle implements Figure double x, y, r;Circle(double u, double v, double m) x=u; y=v; r=m; public void parameter() System.out.println(x+“ “+y+“ “+r); public void area() System.out.println(pi*r*r); ,Triangle t = new Triangle(2, 3); Circle c = new Circle(4, 5, 6); Figure f = t, c;
45、 for (int i =0; i f.length; i+) fi.parameter();fi.area(); ,接口 (interface),接口的继承 extends 将多个接口合并为一个新的接口,interface DC int add(int x, int y); interface DB extends DC int sub(int x, int y); interface DA extends DB int mul(int x, int y); ,interface DY int div(int x, int y); interface DX extends DY int mo
46、d(int x, int y); ,class DD implements DA, DX public int add(int x, int y) return x+y; public int sub(int x, int y) return x-y; public int mul(int x, int y) return x*y; public int div(int x, int y) return x/y; public int mod(int x, int y) return x%y; ,接口 (interface),利用接口实现多重继承(Multiple inheritance) c
47、lass extends 父类 implements 接口,interface CanFight void fight(); interface CanSwim void swim(); interface CanFly void fly(); ,class ActionCharacter public void fight() ,class Hero extends ActionCharacter implements CanFight, CanSwim, CanFly public void swim() public void fly() ,接口 (interface),接口合并时的命名
48、冲突,interface A1 void f(); interface A2 int f(int i); interface A3 int f(); ,class C public int f() return 4; ,class C1 implments A1, A2 public void f() public int f(int i) return 5; ,class C2 extends C implments A2 public int f(int i) return 5; ,class C3 extends C implments A3 public int f() return 5; ,class C4 extends C implements A1 ,