丁保国的博客

收集整理工作生活,点点滴滴

  :: :: 博问 :: 闪存 :: :: :: :: 管理 ::

第七讲 类的继承

主要内容

无继承时类的复用

类继承实现代码复用

继承时方法的重写

super关键字

final修饰的数据、方法和类

 

无继承时类的复用

一个类借用其他类的服务

class Person{  

  public double employed(double salary){

     return salary*0.8;

  }

}

class Test {

  double s;

  Test(double x){s=x;}

  public static void main(String[] a){

     Person p=new Person();

     Test t=new Test(1000);

     System.out.println("He should get "+t.s);

     System.out.println("But he only get "+p.employed(t.s));

  }

}

结论:

²       A类要用到B类的非静态方法时,可临时创建B类对象。

²       借由B类对象调用自身的方法,服务于A类对象。

 

类作为另外一个类的成员

class Person{  

  public double employed(double salary){

     return salary*0.8;

  }

}

class Test {

  double s;

  Test(double x){s=x;}

  Person ps=new Person();

  public static void main(String[] a){

     Test p=new Test(1000);

     System.out.println("He should get "+p.s);

     System.out.println("But he only get "+p.ps.employed(p.s));

  }

}

思考

1.      两个程序有什么区别?

2.      Test类的对象怎么取用于Person类提供的服务?

3.      一个类从另一个类取用服务,有什么好处?

4.      如果Person类需要提供公共的服务,应作何改变?

 

类继承实现代码复用

 

每个类都有父类

如果没有使用extends关键字,则Object类就是缺省的父类。

Object类包含在java.lang包中。所有的类都是从这个类继承而来的。

Object类定义和执行了在Java系统需要的所有类的行为。

 

 

 

类继承的实现

一个类能从其它类继承行为与属性,由此直接实现代码复用。

 

class SubClass extends SuperClass {

    ClassBody

}

程序一:

import javax.swing.*;

class Test extends JFrame{

  public static void main(String[] aa){

     Test t=new Test();

     t.setVisible(true);

     t.setSize(300,200);

  }

}

 

程序二:

class Person{

  int salary;

  void employed(){

     if (salary==0) System.out.println("no job");

     else System.out.println("job");

  }

}

class Children extends Person{

  int age;

  void printAge(){System.out.println("Age:"+age);}

  public static void main(String[] aa){

     Children c=new Children();

     c.salary=560;

     c.age=12;

     c.printAge();

     c.employed();

  }

}

 

继承时的对象初始化

class Art{

  Art(){System.out.println("Art constructor");}

}

class Drawing extends Art{

  Drawing(){System.out.println("Drawing constructor");

  }

}

class Cartoon extends Drawing{

  Cartoon(){System.out.println("Cartoon constructor");}

  public static void main(String[] aa){

     new Cartoon();

  }

}

 

静态变量初始化

运行父类的构造方法(默认或主动)

(按级别高到低的顺序)

实例变量初始化

调用主类的构造方法

 

思考

 

1.    一个类如何去继承另一个类?

1.    一个类继承另一个类时,究竟继承了什么?

2.    类的继承有什么好处?

3.    每个类都有父类吗?

4.    如果类定义时无extends部分,该类的父类是?

5.    多个子类可以继承自一个父类吗?

6.    一个类可以同时继承多个父类吗?

7.    若不希望父类中的某成员被子类所继承,如何实现?

8.    根类Object在哪个软件包中?

9.    对象的初始化时,父类的什么样的构造方法能自动执行?

10.             如何主动调用父类的构造方法?

11.             父类构造方法的执行时机?

 

方法的重写(overriding)

当一个子类继承父类时,子类将自动拥有父类的成员变量和成员方法。

问题:如果父类的某个方法对于子类不合适怎么办?

 

练习:在继承Persons的子类Children中,重写employed方法,输出“A child should study in the school.”

 

重写方法设计要点

²       方法名相同,方法返回类型相同,参数相同

²       重写总是在父类和子类之间

²       重写的意义是修正覆盖父类方法

 

super关键字

是一个特殊的变量,提供了对父类的访问。

每个子类构造方法的第一条语句都是隐含的调用语句super(),如果父类没有这样形式的构造方法,则编译时会出错。

 

super(参数);--------引用父类的构造方法(构造方法不能被继承,要使用父类带参的构造方法时,必须主动调用)

super.变量------访问父类的成员变量

super.方法(参数);------调用父类的成员方法

 

程序一:

class A{

  int x=1;

  int y=2;

}

class B extends A{

  int x=5;

  B(){

     System.out.println(x+y);

     System.out.println(super.x+y);

  }

  public static void main(String[] aa){

     new B();

  }

 

}

程序二:

class GrandParent{

  GrandParent(String s){

     System.out.println("GrandParent "+s);

  }

}

class Parent extends GrandParent{

  Parent(String s){ super("Parent "+s); }

}

class Children extends Parent{

  Children(String s){ super("Children "+s); }

  public static void main(String[] a){

     new Children("lili");

  }

}

 

程序三:

class TestSuper{

  int id;

    TestSuper(int a){id=a; }

    void identify(){System.out.println("SuperClass");}

}

 

class Tests extends TestSuper {

  int id;

  Tests(int a){ super(a);}

    void identify() {

        System.out.println("SubClass");

    }

   

    void test(){

        System.out.println(id);

        System.out.println(super.id);

        identify();

        super.identify(); 

    }

    public static void main(String[] aa){

    (new Tests(5)).test();

    }

}

思考

1.    如何调用父类的构造方法?

2.    调用父类构造方法语句应置于何处?

3.    什么时候需要调用父类的构造方法?

4.  super.变量名this.变量名,分别何意?

 

练习:按照以下给出的步骤,逐步编程。

1.     设计一个Animal类,属性有重量、年龄,行为有:吃(eat)、睡(sleep)、呼吸(breathe)

2.     创建继续Animal的子类fish,呼吸行为不同,改造其方法。

3.     main方法中创建一个fish对象,执行吃、睡、呼吸的方法,执行程序理解重写。

4.     分别给Animal类和fish类创建一无参构造方法。编译执行,分析结果。

5.     fish类的构造方法带参,编译执行并分析结果。

 

final修饰的数据、方法和类

final数据

final 类型 标识符;

如:final double PI=3.14159;

final Circle c=new Circle(5);

final数据意义

²       常数——当类型是基本数据型时

²       不变的对象引用——当类型是对象时

 

程序一:

class TestFinal{

  final double A=5;

  final int B;

  public static void main(String[] aa){

     TestFinal t=new TestFinal();

     System.out.println(t.A++);

     System.out.println(t.B);

  }

}

程序二:

class Fin{

  static int num;

  Fin(){

     num++;

     System.out.println("Fin"+num);

  }

}

class TestFinal{  

  public static void main(String[] aa){

    final Fin f=new Fin();

     f=new Fin();

  }

}

final方法

final方法是不可重写的方法。

final 类型 方法名(参数名){…}

class Fin{

  final void A(){System.out.println("Fin.A()");   }

}

class TestFinal extends Fin{ 

    void A(){System.out.println("TestFianl.A()");}

  public static void main(String[] aa){

     new TestFinal().A();

  }

}

final

final类是不可继承的类。

final 类型 类名{…}

如:String类就是一个final类。

说明:类的说明中,习惯上将public等权限修饰符置于final之前。

如:public final class Test{}

 

final class A{   //final去掉再试

  A(){System.out.println("new A()");}

}

class B extends A{

  B(){System.out.println("new B()");}

  public static void main(String[] aa){

     new B();

  }

}

思考

1.    如何定义一个常数?

2.    final修饰的对象引用有何特别的意味?

3.    final方法一定要在final类中定义吗?

4.    如果一个类的方法不允许子类改写,如何设置?

5.  final类可以被继承吗?

6.  final限制了还是拓广了类的复用?

7.  何时考虑将一个类设定为final类?

 

posted on 2007-07-21 10:35  丁保国  阅读(240)  评论(0编辑  收藏  举报