Class relationship(类的天系) °继承关系( nheritance Relationships) 如何让一个类继承另一个类的成员 接口关系( interfaces) 如何让一个类支持特定的行为 包级关系( Packaging) 如何将类的对象构成逻辑分组 嵌套关系( Inner classes 如何将一个类的声明嵌入另一个类的声明中
Class Relationships (类的关系) • 继承关系(Inheritance Relationships) 如何让一个类继承另一个类的成员 • 接口关系(Interfaces) 如何让一个类支持特定的行为 • 包级关系(Packaging) 如何将类的对象构成逻辑分组 • 嵌套关系(Inner Classes) 如何将一个类的声明嵌入另一个类的声明中
Why need extending elasses' 对真实世界中对象继承关系的支持,满 足面向对象建模技术的需要 对面向对象程序设计语言中对象多态性 ( Polymorphisn的实现 代码复用的一种形式
Why need extending classes? • 对真实世界中对象继承关系的支持,满 足面向对象建模技术的需要 • 对面向对象程序设计语言中对象多态性 (Polymorphism)的实现 • 代码复用的一种形式
class Animal public float weight; public void eat(i.. 则必须满品两个冬供 Cat mycat=new Cato mycat weight=5.5 class Mammal extends AnimaL public int heartrate d mycat. heartRate-80: mycat.long ha -true, public void breath(.. s mycat eatO mycat. breathe, mycat purr; class Cat extends MammaR boolean longHair; 先类中声明的所有p public void purr(0{…}
How to extend a class? • 如果要声明类B继承类A,则必须满足两个条件: (1) 类A非final (2) 类A是public或类B与类A同包, 如果满足条件则可按照以下的语法声明类B: class B extends A { …… } • 类B称为类A的子类(subclass),类A称为类B的父类 或基类(superclass),称类A的父类或父类的父类为 类B的祖先(ancestor) • 子类将拥有在其父类和祖先类中声明的所有public 或protected的成员 class Animal{ public float weight; public void eat(){…} } class Mammal extends Animal{ public int heartRate; public void breath(){…} } class Cat extends Mammal{ boolean longHair; public void purr(){…} } Cat mycat=new Cat(); mycat.weight=5.5; mycat.heartRate=80; mycat.longHair=true; mycat.eat(); mycat.breath(); mycat.purr();
class Ai Classes and Obie static int sfa=100 static void smaf.. 在M中类被表示为一块imtt=10 名和类的静态成员,可以月 int fb==100 类名 void ma(i. Some class static field1 域区方法区 static field2 static field3 A static method1 sfa100 sfb1000 static method2 sma
Classes and Objects in JVM • 在JVM中类被表示为一块内存区域,分别存放类 名和类的静态成员,可以用以下的图形表示: SomeClass static field1 static method1 static field2 static field3 static method2 类名 域 区 方 法 区 class A{ static int sfa=100; static int sfb=1000; static void sma(){…} int fa=10; int fb=100; void ma(){…} } A sfb sma 1000 …… …… sfa 100
Classes and obia ralenew AO: Ara2=ral; 在JM中对象也被表示为一块内存区域,分别存 放到对象所属类的引用和对象的成!可以用以 下的图形表示 类的 引用 classen A ral field1 域区方法 field2 ra2 . A field3 fa 10 fb100 method1 ma method2
Classes and Objects in JVM • 在JVM中对象也被表示为一块内存区域,分别存 放到对象所属类的引用和对象的成员,可以用以 下的图形表示: :classRef field1 method1 field2 field3 method2 类的 引用 域 区 方 法 区 A ra1=new A(); A ra2=ra1; ra1 ra2 A :A fb ma 100 …… …… fa 10
B A A/sfa100 A/sfa100 class B extends Af static int sfb=100 A/sfb1000 A/sfb 1000 int fb=10 B/sfb100 Sna void ma(i.3 Sma . B A A ral=new AO; ra Brbl=new B0; A/fa10 0 ral=rb1 A/fbl100 fb100 rbI B/b10 ma ma
class B extends A{ static int sfb=100; int fb=10; void ma(){…} } A ra1=new A(); B rb1=new B(); ra1=rb1; B A/sfb sma 1000 …… …… A/sfa 100 B/sfb 100 A A/sfb sma 1000 …… …… A/sfa 100 :B A/fb ma 100 …… …… A/fa 10 B/fb 10 :A fb ma 100 …… …… fa 10 ra1 rb1
class Af class B extends At Int a,b: int cd - rb=new BO; AOr BOi a=100 -100 必须完成父类或祖 new BO Object 0 d=0;调用A0 a=0 b=0;调用ohec0 a=100; 返回 c=-100: 返回
Constructors in Subclasses • 子类对象的成员初始化之前必须完成父类或祖 先类对象的成员的初始化,初始化的方式有两 种:隐式初始化和显式初始化 • 隐式初始化:当父类提供了默认的构造函数, 且子类的构造函数中没有显式调用父类的其它 构造函数,则在执行子类的构造函数之前会自 动执行父类的构造函数,直到执行完Object的 构造函数后才执行子类的构造函数 class A{ int a,b; A(){ a=100; } } class B extends A{ int c,d; B(){ c=-100; } } B rb=new B(); new B() A Object a=100; …… c=-100; c=0; d=0; a=0; b=0; 调用A() 调用Object() 返回 返回
Constructors in Subclasses 显式初始化:可以在子米浩函数的一 语句通过 super0或 supe class B extends A 构造函数或特定签名的intc; class At d B(int i 构 错误 int a.b: A(int c, int dt B(int i, int j, int k)t a-c, b=d super(,j) k:
Constructors in Subclasses • 显式初始化:可以在子类构造函数的第一条 语句通过super()或super(…)调用父类的默认 构造函数或特定签名的构造函数 • 当父类没有提供默认构造函数时,必须在子 类构造函数第一条语句通过super(…)完成父 类对象成员的初始化工作 class A{ int a,b; A(int c, int d){ a=c; b=d; } } class B extends A{ int c; B(int i){ c=i; } } 错误 B(int i, int j, int k){ super(i, j); c=k; }
Reference Types Compatibility 赋值兼容性规则: BRb=new BO 时,赋 值号Aral=h 号左边 的对 A ra2=new B0; a Obiect aob=ral 2) 长型必须 与方 Object strobl= new String(“good”); Object intobj =new Integer(100); 子类型 Nu对豕与所得时用天术所有 引用类型的变量都可被赋值为nul
Reference Types Compatibility • 赋值兼容性规则: (1) 对引用类型的变量进行赋值操作时,赋 值号右边的表达式的类型必须与赋值号左边 的对象引用类型相同或是其子类型 (2) 方法的return语句返回的结果的类型必须 与方法声明中的返回类型相同或是其子类型 • Null对象引用与所有的引用类型兼容,所有 引用类型的变量都可被赋值为null B rb=new B(); A ra1=rb; A ra2=new B(); Object aobj=ra1; Object strobj=new String(“good”); Object intobj=new Integer(100);
Reference Types Casting 引用类型间的类型转换( Conversion)又称为造型 鱼E (Ca 下造 型( Object objl= new String(“good”) 向上造型 Object obj2=new Integer(100) 向 子 tring strl==( String)objl 向下造型弓 用向 a. Integer intl=(Integer)obj2 Integer int2=(Integer)obj1; 造型错误指 将某天天主时赋 值操作必须进行显式的类型转换 注意:向下造型可能存在一定的类型安全风险
Reference Types Casting • 引用类型间的类型转换(Conversion)又称为造型 (Casting),可以分为向上造型(Upcasting)和向下造 型(Downcasting)两种情况 • 向上造型又称为“Widening Conversion”,是指将 子类类型的引用赋值给其父类或祖先类类型的引 用,赋值操作中包含了隐式的类型转换 • 向下造型又称为“Narrowing Conversion”,是指 将某类类型的引用赋值给其子类类型的引用,赋 值操作必须进行显式的类型转换 注意:向下造型可能存在一定的类型安全风险 Object obj1=new String(“good”); Object obj2=new Integer(100); String str1=(String)obj1; Integer int1=(Integer)obj2; Integer int2=(Integer)obj1; 向上造型 向下造型 造型错误