[core.java基础教程]_杨帆_07.java面向对象编程-高级类特性

killerdongbo

贡献于2013-05-12

字数:0 关键词: Java开发

http://gzyangfan.spaces.live.com/blog/ gzyangfan@gmail.com  创建 static 变量、方法和初始值设定项  创建 final 类、方法和变量  创建和使用枚举类型  使用静态导入语句  创建抽象类和方法  创建和使用接口  理解和认识内部类 学习目标 gzyangfan@gmail.com  static 关键字用作变量、方法和嵌套类的修饰符。  static 关键字声明属性或方法与整个类而不是类的任 何特定实例相关。  因此,静态成员经常称为类成员,例如,类属性或类 方法。 static 关键字 gzyangfan@gmail.com  类属性在类的 所有实例中共享: 类属性 public class Count { // 这是一个类属性 private static int count = 0; // 这是一个对象/实例的属性 private int serialNumber; public Count() {count++; serialNumber = count; } public int getId() { return serialNumber; } } gzyangfan@gmail.com  如果静态成员是 public: public class OnlineUser { public static int count; }  可以直接从外访问它而无需实例化该类: public class OtherClass { public static void main(String[] args) { OnlineUser.count++; } } 类属性 gzyangfan@gmail.com  static 方法被称为类方法/静态方法。  类实例可以直接使用类方法/属性,但类方法中不能 使用实例的方法/属性。 类方法 public class Count { private static int count = 0; private int serialNumber; public static int getCount() { return count; } } gzyangfan@gmail.com  类方法可被直接调用,无需创建该类的任何实例:  输出结果是: Count : 0 Count : 1 类方法 public class MethodDemo { public static void main(String[] args) { System.out.println("Count : " + Count.getCount()); Count c = new Count(); System.out.println("Count : " + Count.getCount()); } } gzyangfan@gmail.com  一个类可以在静态块(该静态块不存在于方法体内) 中包含代码。  在类加载后初始化时,静态块代码仅执行一次。  通常,静态块用于初始化静态(类)属性。 静态初始值设定项 gzyangfan@gmail.com public class InitField { static int number; static User userOne = initUser(); static User userTwo; static { User user = new User(); user.setName("May"); userTwo = user; } private static User initUser() { User result = new User(); result.setName("frank"); return result; } } 静态初始值设定项示例 gzyangfan@gmail.com  在类中除了有静态代码块外,还可以有普通代码块。  静态块代码仅执行一次。  普通代码块每次实例化都会被执行一次。  通常,普通代码块用于初始化实例的属性。 普通代码块和静态代码块 gzyangfan@gmail.com  被 final 修饰的类 ◦ 该类不能被子类化(这样可保障类的安全) ◦ final 类中的所有方法都默认为 final  被 final 修饰的方法 ◦ 该方法不能被覆盖 ◦ final 方法无需支持动态绑定,因此效率更高  被 final 修饰的变量/属性是一个常数。 ◦ final 变量只能设置一次,但赋值可以在声明之外单独出现; 此变量称为空 final 变量。 ◦ 在使用空 final 变量/属性使用前,必须先设值。 ◦ 空 final 实例属性必须在构造器或代码块中设值。 final 关键字 gzyangfan@gmail.com public class FinalDemo { public static void main(String[] args) { // final 变量范例 final int x = 10; // x = 20; // 多次赋值是不被允许的 final User user; // 空 final 变量可被赋值一次 user = new User(); } } final 变量示例 gzyangfan@gmail.com public class Field { private final int x = 100; private final User userOne; private final User userTwo; { userOne = new User(); userOne.setName("frank"); } public Field() { userTwo = new User(); userTwo.setName("may"); } } final 属性示例 gzyangfan@gmail.com  常数是静态的 final 变量。 public class Math { // 常数的 PI 值 public static final double PI = 3.14159; public static double circleArea(double radius) { return PI * radius * radius; } } final 属性示例 gzyangfan@gmail.com public class SystemProperty { public final static String globalName; static { globalName = System.getProperty("MyGlobalName"); } public static void main(String[] args) { System.out.println(SystemProperty.globalName); } }  运行结果: java –DMyGlobalName=frank [完整类名] frank 外部指定系统常量值示例 gzyangfan@gmail.com  枚举类型是编程中的一个普通用语,其本质可以理解 为有限元素的集合。  在 Java5 之前,需要使用 public final static 来实现。 旧世界的枚举 public interface IGrade { /** 忧 */ char EXCELLENT = 'A'; /** 良 */ char GOOD = 'B'; /** 中 */ char PASS = 'C'; /** 差 */ char FAILURE = 'D'; } gzyangfan@gmail.com  现在您可以创建类型安全的枚举类型:  新枚举类型的优势: ◦ 类型安全/值安全 ◦ 良好的命名空间 Java5 的枚举 public enum GradeBasic { /** 忧 */EXCELLENT, /** 良 */GOOD, /** 中 */PASS, /** 差 */FAILURE; } gzyangfan@gmail.com  高级枚举类设计范例: Java5 的枚举 public enum GradeEnhanced { A(100, 85), B(85, 70), C(70, 60), D(60, 0); private int max; private int min; private GradeEnhanced(int max, int min) { this.max = max; this.min = min; } public int getMax() { return max; } gzyangfan@gmail.com  续上页: Java5 的枚举 public int getMin() { return min; } public static GradeEnhanced valueOf(int grade) { if (grade < 0) throw new IllegalArgumentException( "grade must >= 0"); if (grade >= A.getMin()) return A; if (grade >= B.getMin()) return B; if (grade >= C.getMin()) return C; return D; } } gzyangfan@gmail.com  单例模式就是,确保一个类只有一个实例,并提供全 局访问点。  饿汉式,示例:  用枚举实现的饿汉式,示例: 单例模式 Singleton public class Greedy { private final static Greedy me = new Greedy(); private Greedy() { } public static Greedy getInstance() { return me; } } public enum Enum {INSTANCE; } gzyangfan@gmail.com  懒汉式,示例: 单例模式 Singleton public class Lazy { private Lazy() { } private volatile static Lazy me; public static Lazy getInstance() { if (me == null) synchronized (Lazy.class) { if (me == null) me = new Lazy(); } return me; } } 在 Java5 以前的版本中 volatile 关键字会导致双重检查加 锁的方法失效,因此不能使用该种方式。 gzyangfan@gmail.com  静态导入从类导入静态成员: import static ..;  OR import static ..* ; 静态导入 gzyangfan@gmail.com  用 abstract 修饰的类是抽象类,他被定义为永远不 会也不能被实例化为具体的对象。它往往用于定义一 种抽象上的概念,在类的继承关系中它往往被定义在 较上层的位置。  抽象类是不完整的,并且它只能用作基类。  它与非抽象类的不同在于: ◦ 抽象类不能直接实例化 ◦ 允许(但不要求)抽象类包含抽象方法。 抽象类 抽象方法不能是私有的,默认修饰的抽象方法可以限制子 类必须与抽象类在同一个包中。 gzyangfan@gmail.com  定义一个操作中算法的骨架,将一些步骤的执行延迟 到其子类中。  抽象摸板角色: ◦ 定义了一个或多个抽象操作,以便让子类实现。 ◦ 定义并实现了一个摸板方法。  具体摸板角色: ◦ 实现父类所定义的一个或多个抽象方法。 ◦ 可以有任意多个具体摸板角色,实现同一个抽象模板角色。 ◦ 每一个具体摸板角色都可以给出这些抽象方法的不同实现 模板模式 Template gzyangfan@gmail.com 模板模式 Template gzyangfan@gmail.com  模板类,示例: 模板模式示例 public abstract class Column { /** 高度属性 */ protected double height; public Column(double height) { this.height = height; } /** 获取 底面积 */ public abstract double getArea(); /** 获取 体积 */ public double getVolume() { return getArea() * height; } } gzyangfan@gmail.com  具体类,示例: 模板模式示例 public class Round extends Column { /** 半径 */ private double radius; public Round(double radius, double height) { super(height); this.radius = radius; } @Override public double getArea() { return Math.PI * radius * radius; } } gzyangfan@gmail.com  接口使抽象的概念更深入了一层。我们可将其想象 为一个“纯”抽象类。  接口只提供一种形式,并不提供实施的细节。  接口这样描述自己:“对于实现我的所有类,看起 来都应该象我现在这个样子”。所以我们常把接口 用于建立类和类之间的一个“协议”。 什么是接口 gzyangfan@gmail.com  Java 接口中所有方法都不包含实现。  Java 接口也可以声明数据成员,但它们默认都为 static 和 final。  许多无关联类能实现同样的接口。  类能实现许多无关联接口。  Java 类的语法如下所示: < 修饰符> class < 名称> [extends < 超类>] [implements < 接口> [,< 接口>]* ] { < 成员声明>* } 接口 interface gzyangfan@gmail.com 接口示例  接口定义  类实现 public interface Flyer { void fly(); } public class Airplane implements Flyer { @Override public void fly() { System.out.println("飞机在天上飞!"); } } gzyangfan@gmail.com 接口示例 多个不同的类也可以实现相同的接口,但这并不他们各自 具有自己方法和数据。 gzyangfan@gmail.com 接口示例 多个具体的实现类也可以具有自己的类层次结构,接口可 把这些不同的类组织起来。 gzyangfan@gmail.com 多继承 Java通过接口来解决多继承的问题,多继承所表达的含义 为:“x从属于a,也从属于b,也从属于c……” gzyangfan@gmail.com 接口使用包括如下内容:  声明一个或多个类需要实现的方法  确定对象的编程接口,而不暴露类的实际主体  捕获无关联类之间的相似性,而无需强加类关系  通过声明一个实现若干接口的类来模拟多重继承  必要时可通过继承将几个小接口,合并成大接口,或 给接口添加方法 接口的使用 gzyangfan@gmail.com  适配器模式就是将一个类的接口,转换成客户期望的 另一个接口。适配器可让原本不兼容的类可合作无间。  概念类图: 适配器模式 Adapter gzyangfan@gmail.com  Client : 适配器模式示例 public class IntelMainborad { private Intel cpu; /** 该方法代表了开机动作 */ public void start() { cpu.power(); } // Getter and Setter … public Intel getCpu() { return cpu; } public void setCpu(Intel cpu) { this.cpu = cpu; } } gzyangfan@gmail.com  Adapter :  Adaptee : 适配器模式示例 public interface Intel { /** 该方法代表 Intel CPU 的工作方式 */ void power(); } public class Phenom2 implements AMD { @Override public void ac() { System.out.println("AMD Phenom II 在工作!"); } } gzyangfan@gmail.com  ConcreteAdapter : 适配器模式示例 public class AMD2IntelAdapter implements Intel { private AMD amd; @Override public void power() { amd.ac(); } // Getter and Setter... public AMD getAmd() { return amd; } public void setAmd(AMD amd) { this.amd = amd; } } gzyangfan@gmail.com  内部类就是定义来类内部的类。  可分为静态内部类和非静态内部类两大类。  非静态内部类又可细分为: ◦ 成员内部类 ◦ 局部内部类 ◦ 匿名内部类  内部类允许将逻辑上同属性的类组合到一起,并可在 一个类中控制另一个类的状态。 内部类 gzyangfan@gmail.com  创建内部类实例时, 外部类的实例必须已经存在。  内部类实例自动持有对外部类实例的引用,内部类实 例可直接访问持有它的外部类实例的成员。  外部类实例可通过具体的引用,直接操作对应内部类 实例的成员。  成员内部类中不能定义静态成员,只能定义对象成员。  当内部类与外部类有同名的成员时,内部类可通过 外部类名.this.变量名 访问外部类成员。 成员内部类 gzyangfan@gmail.com  与局部变量一样, 不能被访问控制符修饰,不过可被 final 和 abstract 修饰。  只能在当前方法中使用。  不能包含静态成员。  在局部类中定义的内部类也不能被访问控制符修饰。  局部内部类和成员内部类一样, 可以访问外部类的成 员;此外,局部内部类还可以访问所在方法中 final 修饰的参数或变量。 局部内部类 gzyangfan@gmail.com  匿名内部类没有构造方法, 但是可以调用父类的构造 方法。  匿名内部类尽管没有构造方法, 但是可以在匿名内部 类中提供一段实例初始化代码。  除了可以在外部类的方法内定义匿名类之外, 还可以 在声明成员变量时定义匿名内部类。  匿名内部类除了可以继承外, 还可以实现接口(通常以 继承抽象类和实现接口的使用方法居多)。  匿名内部类和局部内部类一样, 都可以访问外部类的 所有成员,,如果匿名类在一个方法中, 还可以访问 final 修饰的变量和参数 匿名内部类 gzyangfan@gmail.com  静态内部类的实例不会自动持有外部类实例的引用, 因此在创建静态内部类实例, 不必创建外部类的实例。  静态内部类可以直接访问外部类的静态成员。  静态内部类中可以定义静态成员和对象成员。  其它类可以通过完整类名来访问静态内部类的静态成 员。 静态内部类

下载文档,方便阅读与编辑

文档的实际排版效果,会与网站的显示效果略有不同!!

需要 2 金币 [ 分享文档获得金币 ] 0 人已下载

下载文档

相关文档