34 35 } 36 }
Person_s.print_count();// 通过类名调用类方法
? 程序结果 count=1 count=1 Jack is 21 years old. count=2 Tom is 18 years old. 共有 2个对象.
调用析构方法后还有 1个对象. count=1 ? 程序说明:
Person_s类中的变量name、age是实例变量,对于不同的对象p1和p2各有自己的值。所以程序的36行的执行结果是输出语句?Jack is 21 years old.”,程序的38行的执行结果是输出语句?Tom is 18 years old.” Person_s类中的变量count是类变量,系统运行时,只为该类的第一个对象p1分配内存单元,其后创建的对象p2共享一个count变量。所以在创建了对象p2后,count的值为2。但是,程序的第36行通过对象p1调用析构方法,count的值减1后为1。
? Java类就包括两种成员:实例成员和类成员。类成员也称为静态成员。使用static修饰的成员称为类成员。
类的成员变量有实例方法和类方法两种。没有static修饰的方法称为实例方法。实例方法体中既可以访问类变量,也可以访问实例变量,实例方法只能通过对象来调用。
用static修饰的方法称为类方法或静态方法。类方法体中只能访问类变量。类方法既可以通过对象来调用,也可以通过类名调用,如程序的第31行和37行。
在程序中也可以使用析构方法finalize()随时销毁对象。Java的每个类都有一个析构方法,用于将资源返回给系统。方法finalize()没有参数,也不返回值。
设计亚洲人的类(继承)
1 class Asian extends Person { 2 3 4 5 6
static String skinColor = \黄色\static String hairColor = \黑色\String country;
Asian(String name,int age,String country) {
7 super(name,age); 8 this. Country =country;
9 System.out.println(\调用了子类中的构造方法========\10 }
11 public void print() { 12
System.out.println(getName() + \,皮肤是:\的。\
13 System.out.println(getName() + \,头发是:\的。\14
System.out.println(getName() + \是:\人。\
15 } 16 }
17 public class Test { 18
public static void main(String args[]) {
19 Asian s = new Asian(\紫怡\中国\创建子类对象 20 s.introduction();// 调用父类的方法 21
s.print(); // 调用子类的方法
22 } 23 } 运行结果如下:
========调用了子类中的构造方法======== 我的名字叫紫怡 我的年龄是20岁 紫怡,皮肤是:黄色的。 紫怡,头发是:黑色的。 紫怡是:中国人。
继承:在已有类的基础上快速构造出新类的过程;派生:在构造新类的同时并新增新的特性的过程。
基(父)类:被继承特性的类;派生(子)类:在基类的基础上新创建出的类。 为什么要继承派生:实体(对象)之间不仅在横向方面具有关联特性,在纵向上也存在继承与派生的特性(遗传与变异);如果编程时能充分利用此特性将可快速地构造出新类。
实现继承的格式为: class 子类名 extends 父类
子类中如何进行继承与派生父类(可以采用简单的比较法)。常用的手段有: 继承基类中的原始成员(当派生类中未定义出该成员时将自动采用继承)。 覆盖(重写或替换)父类中的成员方法:当父类中的某些成员方法不再适合子类的需要时,在子类中应重写出自己的成员方法。
扩充增强子类功能:当子类要求具有新的能时,应添加出该功能(增添新的成员)。代码8.6中print()方法是新增的功能。
1 class Father // 父类 2 {
3 4 5
public int f = 5; int Move(int x) {
return 65 + x;
6 } 7 } 8
9 class Fils extends Father // 子类 10 {
11 public int boy = 6; 12 int FilsMove(int x) { 13 14
}
return 165 + x;
15 }
16 public class fatherFils // 应用类 17 { 18 19
public static void main(String[] args) {
Father s = new Fils(); // 父类可以用子类实例化,因为子类包含了父类的内容 System.out.println(s.Move(55));
// System.out.println(s.FilsMove(55)); //子类的东西是不能直接用的,所以这样写不可以的 System.out.println(((Fils) s).FilsMove(55)); //父类想用子类的东西可用强制数据类型转换 // Fils s1=new Father(); //子类用父类来实现是错误的 Father s2 = new Father();
20 21
22 23 24
25 Fils s3 = new Fils(); 26
s2.f = 777;
27 28 29 30 31 32 33 } 34 }
s3.boy = 88; s3.f = 999;
s2 = s3; // 子类可以赋值给父类,比如
// 当然,一般来说,子类的boy数据在父类是不能直接看到了 System.out.println(s2.f);
System.out.println(((Fils) s2).boy);// 要显示boy数据,可以使用强制数据类型转换
说明:强制数据类型转换,可以在父子关系中应用,但主要用于父类转成子类,因为子类包含着父类的内容,所以子转成父的转换是没必要的。
子类对父类方法的重写(方法的重写)
1 class Person{ 2
。。。。。。
3 // 略,与原代码一致
4 public void eat() // 父类定义的eat()方法 5 { 6
System.out.println(\每个人都要吃饭\
7 } 8 }
9 class Chinese extends Person{ 10 String province;
11 public Chinese(String name,int age,String province) 12 {
13 super(name,age); // 直接指明调用父类中有两个参数的构造方法