1.代码复用的方式:
(1)类组合
如一个 喷水系统,需要用到水资源.
class WaterSource { private String s; //水资源 WaterSource() { System.out.println("WaterSource()"); s = new String("Constructed"); } //喷洒系统 public class SprinklerSystem { WaterSource source = new WaterSorce(); }
实际就是一个新类里引用很多其它类,这些类低耦合,高复用.
(2)类继承
衍生类继承父类,衍生类既可以使用父类的方法,又能扩展新的方法.(java面向对象三大特性之一)
注意:
创建衍生类的一个对象时, 它在其中包含了父类的一个“子对
象”。这个子对象就象我们根据基础类本身创建了它的一个对象。从外部看,基础类的子对象已封装到衍生
类的对象里了.
所以,会一层一层的 “从上往下“ 调用父类的构造器,直到上面没父类了。
若衍生类构造器和父类构造器的 变量 不一样,会报错.解决方法是创建相同的构造器,或在衍生类中用super(xx)引用到父类某个构造器
p r o t e c t e d 关键字
若变量或方法用protected关键字,只能通过同一个包的类或继承才能使用到.
(3)组合和继承一起用
class Plate { Plate(int i) { System.out.println("Plate constructor"); } } class DinnerPlate extends Plate { DinnerPlate(int i) { super(i); System.out.println( "DinnerPlate constructor"); } } class Utensil { Utensil(int i) { System.out.println("Utensil constructor"); } } class Spoon extends Utensil { Spoon(int i) { super(i); System.out.println("Spoon constructor"); } } class Fork extends Utensil { Fork(int i) { super(i); System.out.println("Fork constructor"); } } class Knife extends Utensil { Knife(int i) { super(i); System.out.println("Knife constructor"); } } // A cultural way of doing something: class Custom { Custom(int i) { System.out.println("Custom constructor");146 } } public class PlaceSetting extends Custom { Spoon sp; Fork frk; Knife kn; DinnerPlate pl; PlaceSetting(int i) { super(i + 1); sp = new Spoon(i + 2); frk = new Fork(i + 3); kn = new Knife(i + 4); pl = new DinnerPlate(i + 5); System.out.println( "PlaceSetting constructor"); } public static void main(String[] args) { PlaceSetting x = new PlaceSetting(9); } } ///:
2.final关键字使用
(1)final修饰变量
变量会设置成常数. 无论 static 还是 final 字段,都只能存储一个数据,而且不得改变。
(2)final修饰方法
该方法不能被子类覆盖重写
(3)final修饰类
类不能被继承.
采用 final 方法的第二个理由是程序执行的效率。将一个方法设成 final 后,编译器就可以把对那个方法的所有调用都置入“嵌入”调用里。只要编译器发现一个 final 方法调用,就会(根据它自己的判断)忽略为执行方法调用机制而采取的常规代码插入方法(将自变量压入堆栈;跳至方法代码并执行它;跳回来;清除堆栈自变量;最后对返回值进行处理)。相反,它会用方法主体内实际代码的一个副本来替换方法调用。这样做可避免方法调用时的系统开销。当然,若方法体积太大,那么程序也会变得雍肿,可能受到到不到嵌入代码所带来的任何性能提升。因为任何提升都被花在方法内部的时间抵消了。 Java 编译器能自动侦测这些情
况,并颇为“明智”地决定是否嵌入一个 final 方法。然而,最好还是不要完全相信编译器能正确地作出所有判断。通常,只有在方法的代码量非常少,或者想明确禁止方法被覆盖的时候,才应考虑将一个方法设为final。
private修饰的方法都是自动变final,因为方法私有.
4. 继承初始化顺序
昆虫和甲虫例子:
class Insect { int i = 9; int j; Insect() { prt("i = " + i + ", j = " + j); j = 39; } static int x1 =prt("static Insect.x1 initialized"); static int prt(String s) { System.out.println(s); return 47; } } public class Beetle extends Insect { int k = prt("Beetle.k initialized"); Beetle() { prt("k = " + k); prt("j = " + j); } static int x2 = prt("static Beetle.x2 initialized"); static int prt(String s) { System.out.println(s); return 63; } public static void main(String[] args) { prt("Beetle constructor"); Beetle b = new Beetle(); } } ///:~
该程序的输出如下:
static Insect.x initialized
static Beetle.x initialized
Beetle constructor
i = 9, j = 0
Beetle.k initialized
k = 63
j = 39
1先初识化父类static的变量,后父类static方法,再子类static变量和方法.
2再初始化父类变量和子类变量.
3再初始化父类构造器和子类构造器.
多态
什么是多态?
现实中的多态:水果、人、动物,水果是一个大的种类,小的种类为香蕉,西瓜,苹果等等,把这样的一种大的种类包含很多小种类称为多态.
java中多态的定义:指允许不同类的对象对同一消息做出响应。即同一消息可以根据发送对象的不同而采用多种不同的行为方式。(发送消息就是函数调用)
如 :接口和实现类,一个接口可以实现多个实现类,并且每个实现类可实现不同功能.
介绍多态更详细的文章:http://www.cnblogs.com/jack204/archive/2012/10/29/2745150.html
Java中默认对象引用全部是晚绑定,只有static和final类型的引用时早绑定或编译时绑定。
多态的优势是:
程序的可扩张性好,无论添加多少个子类,基类的接口都不用改变,只需要在子类对应方法中提供具体实现即可,也就是所谓的将程序变化的部分和程序保持不变的部分分离。降低类之间耦合度
注意:只有正常的方法可以使用多态,字段和静态方法没有多态机制。