Reusing Class
Agenda•   概述•   组合•   继承•   子类初始化•   super关键字•   委托•   @Override注解•   继承 vs. 组合•   protected•   向上转型•   final关键字
概述• 不要重复自己(Don’t Repeat Yourself/DRY)是  编码的一个基本原则. 重复会带来极严重的  代码可维护性问题.• Java通过继承或者组合的方式实现对已有类  功能的重用;
组合• 组合是指在一个java类中引用另一个类的对象, 访问   该类的成员及方法从而达到重用的目的. 比如: 一个   喷水系统需要有水源装置, 这里创建2个类   SprinklerSystem/WaterSource, 其中Sprinkl...
继承• 当创建一个自定义的class时就会发生继承:1), 显式使用extends关键字继承某个类;2), 如果没有显式继承, 新建的类会自动继承Object基类.• 通过继承, 父类的方法可以在子类调用, 从而达到重用的目的; 比如:clas...
子类初始化• 通过继承得到的子类是如何进行初始化的  呢? 在进行子类的初始化之前, 需要先逐级  对基类进行初始化(Java中可以显式调用基类的构造器进行  初始化, 如果不指定则调用基类的默认构造器),基类初始化完  毕之后会产生一个基类子...
子类初始化• 参考:        Class A           Note: 以创建一个C类对象为例                          C c = new C(); 2          extends   3      ...
super关键字• 默认情况下初始化子类时会调用父类的默  认构造器, 可以在子类的构造器中通过super  调用指定的父类构造器, 比如:Class A {   A() {...}   A(int i) {...}}Class B {   B...
委托                 Delegation• 委托是介于继承和组合之间的重用方式, 通过保存某个   类对象的引用(组合), 并且提供与该类相同的接口(继承),   示例:Class A {   void f1(int i) {...
@Override注解• @Override注解用于表示子类覆盖了基类中的某个方法,   如果实际没有发生覆盖, 那么会产生编译错误, 示例:class A {   void f1() {...}   void f2(int i) {...}}...
继承 vs. 组合• 如何在继承与组合之间做出选择? 取决于是  否需要提供与被重用类相同的接口, 如果需  要则使用继承, 否则使用组合; 另外继承表  达的是一种is-a的关系, 因此需要额外从类本  身的建模意义上进行考虑.• demo/...
protected• 类的受保护成员允许当前类, 子类, 以及同一  个包下面的其他类访问(package access);• 尽管java提供了受保护访问权限, 但是仍建  议优先使用private权限;• 示例: demo/Demo7.java
向上转型              Upcasting• 向上转型是指将对象赋值给指向其父类的引用, 比如Class    B extends A {...}, 可以编写如下代码:A obj = new B(); // 这里创建B对象, 赋值给...
final关键字• final关键字在不同的使用场合下会有不同的  意义, 大体上用来声明某个类/成员是不可改  变的;• final类:  表示该类不能被继承;• final方法: 表示该方法不能被子类覆盖;• final属性: 表示该属性不...
final类• 出于设计的原因, 某个不应该被继承, 可以将   它声明为final; 这通常见于某些工具类.• 示例:final Class A {......}class B extends A {...} // 编译错误
final方法• 出于两个原因, 可以将方法声明为final:1), 该方法不应该在子类中被覆盖;2), 效率; 将方法声明为final, 可以在一定程度上提高效   率.• 示例:class A{   public final void f(...
Pitfall: private method• private方法默认是final的, 不能在子类中覆盖一   个private方法; 如果你在子类重写了一个private   方法, java编译器不会对此提出警告.• 示例:class A...
final方法参数• 当使用final修饰方法的形参时, 该参数在方法调用过   程中不能被重新赋值:1), 如果该参数是原语类型, 那么该参数不能被重新赋   值, eg:void f(final int i)...在方法体内, 不能使用 i...
final属性• 将属性声明为final,1), 如果属性在声明时进行了初始化, 那么该属性不能被重新赋值; eg:final int i = 0; // i 不能被重新赋值2), 如果声明时没有初始化(Blank final), 那么必须在构...
END
Upcoming SlideShare
Loading in …5
×

7, reusing classes

197 views

Published on

About java, how to reuse classes

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
197
On SlideShare
0
From Embeds
0
Number of Embeds
8
Actions
Shares
0
Downloads
0
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

7, reusing classes

  1. 1. Reusing Class
  2. 2. Agenda• 概述• 组合• 继承• 子类初始化• super关键字• 委托• @Override注解• 继承 vs. 组合• protected• 向上转型• final关键字
  3. 3. 概述• 不要重复自己(Don’t Repeat Yourself/DRY)是 编码的一个基本原则. 重复会带来极严重的 代码可维护性问题.• Java通过继承或者组合的方式实现对已有类 功能的重用;
  4. 4. 组合• 组合是指在一个java类中引用另一个类的对象, 访问 该类的成员及方法从而达到重用的目的. 比如: 一个 喷水系统需要有水源装置, 这里创建2个类 SprinklerSystem/WaterSource, 其中SprinklerSystem将 会重用WaterSource类, 示例:class WaterSource {......}class SprinklerSystem{ WaterSource source; // 通过组合进行重用 ......}• 示例: demo/Demo1.java
  5. 5. 继承• 当创建一个自定义的class时就会发生继承:1), 显式使用extends关键字继承某个类;2), 如果没有显式继承, 新建的类会自动继承Object基类.• 通过继承, 父类的方法可以在子类调用, 从而达到重用的目的; 比如:class Parent { void f1(); void f2();}class Child extends Parent {...}// 调用父类的方法Child c = new Child();c.f1();c.f2();• 示例: demo/Demo2.java
  6. 6. 子类初始化• 通过继承得到的子类是如何进行初始化的 呢? 在进行子类的初始化之前, 需要先逐级 对基类进行初始化(Java中可以显式调用基类的构造器进行 初始化, 如果不指定则调用基类的默认构造器),基类初始化完 毕之后会产生一个基类子对象, 该子对象将 会被之后创建的子类对象引用. 接下则会开 始子类的初始化工作;• 示例: demo/Demo3.java
  7. 7. 子类初始化• 参考: Class A Note: 以创建一个C类对象为例 C c = new C(); 2 extends 3 需要按如下顺序执行: Class B 1, 先需要对C的基类B进行初始化; 2, B还有基类A, 先进行基类A的初始化; 3, A初始化完毕, 执行B的初始化; 1 extends 4 4, B初始化完毕, 执行C的初始化 Class C
  8. 8. super关键字• 默认情况下初始化子类时会调用父类的默 认构造器, 可以在子类的构造器中通过super 调用指定的父类构造器, 比如:Class A { A() {...} A(int i) {...}}Class B { B(int i) {super(i); ...} // 调用基类的A(int)构造器}• 示例: demo/Demo4.java
  9. 9. 委托 Delegation• 委托是介于继承和组合之间的重用方式, 通过保存某个 类对象的引用(组合), 并且提供与该类相同的接口(继承), 示例:Class A { void f1(int i) {...} String f2() {...}}Class B { A a = new A(); // 保存A对象的引用 void f1(int i) {a.f1(i);} // 一致的接口, 并调用A的方法 String f2() {return a.f2();}}• 示例: demo/Demo5.java
  10. 10. @Override注解• @Override注解用于表示子类覆盖了基类中的某个方法, 如果实际没有发生覆盖, 那么会产生编译错误, 示例:class A { void f1() {...} void f2(int i) {...}}class B extends A { @Override void f1() {...} // @Override void f2(String s) {...} // 编译错误, 重载而非覆盖}
  11. 11. 继承 vs. 组合• 如何在继承与组合之间做出选择? 取决于是 否需要提供与被重用类相同的接口, 如果需 要则使用继承, 否则使用组合; 另外继承表 达的是一种is-a的关系, 因此需要额外从类本 身的建模意义上进行考虑.• demo/Demo6.java
  12. 12. protected• 类的受保护成员允许当前类, 子类, 以及同一 个包下面的其他类访问(package access);• 尽管java提供了受保护访问权限, 但是仍建 议优先使用private权限;• 示例: demo/Demo7.java
  13. 13. 向上转型 Upcasting• 向上转型是指将对象赋值给指向其父类的引用, 比如Class B extends A {...}, 可以编写如下代码:A obj = new B(); // 这里创建B对象, 赋值给指向A的引用• 向上转型始终是安全的, 继承本身表示的就是一种is-a关 系;• 在调用方法时经常会发生向上转型; 示例:方法声明:void f(java.util.List list);方法调用:java.util.List list = new ArrayList();...f(list); // Upcasting, 由ArrayList到List
  14. 14. final关键字• final关键字在不同的使用场合下会有不同的 意义, 大体上用来声明某个类/成员是不可改 变的;• final类: 表示该类不能被继承;• final方法: 表示该方法不能被子类覆盖;• final属性: 表示该属性不能被修改;• final参数: 该参数在方法里面不能被修改;
  15. 15. final类• 出于设计的原因, 某个不应该被继承, 可以将 它声明为final; 这通常见于某些工具类.• 示例:final Class A {......}class B extends A {...} // 编译错误
  16. 16. final方法• 出于两个原因, 可以将方法声明为final:1), 该方法不应该在子类中被覆盖;2), 效率; 将方法声明为final, 可以在一定程度上提高效 率.• 示例:class A{ public final void f()...}class B extends A { public void f()... // 编译错误, final方法不能被覆盖}• 示例: demo/Demo8.java
  17. 17. Pitfall: private method• private方法默认是final的, 不能在子类中覆盖一 个private方法; 如果你在子类重写了一个private 方法, java编译器不会对此提出警告.• 示例:class A { private void f() ... // 默认为final}class B extends A { public void f() ... // 不是覆盖}
  18. 18. final方法参数• 当使用final修饰方法的形参时, 该参数在方法调用过 程中不能被重新赋值:1), 如果该参数是原语类型, 那么该参数不能被重新赋 值, eg:void f(final int i)...在方法体内, 不能使用 i = ...重新赋值2), 如果该参数是某个引用类型, 则表示该引用不能指 向其他的对象, eg:void f(final List list)...不能使用list = ...进行赋值, 但是可以对象本身的内容可以改变, 比如在方法内调用list.add(...)• 示例: demo/Demo9.java
  19. 19. final属性• 将属性声明为final,1), 如果属性在声明时进行了初始化, 那么该属性不能被重新赋值; eg:final int i = 0; // i 不能被重新赋值2), 如果声明时没有初始化(Blank final), 那么必须在构造器中对该属性进行初始化; eg:class A { final int i; A() { i = 3; }}• final经常与static结合使用用于声明常量(Constants), eg:public static final int VALUE_ONE = 1;• 示例: demo/Demo10.java
  20. 20. END

×