面向对象方法的特性:抽象、封装、继承、多态
抽象:抓取问题的精髓
抽象类:代表一个抽象概念的类;规定整个类家族(管理抽象类的子类)必须具备的属性和行为
-
- 类名前加修饰符 abstract 这个类没有具体实例对象,不能使用new方法实例化,只能用作超类被子类继承。
- 成员范围与常规类一致(尤其包括非抽象方法)。
- 包含抽象方法时,用abstract修饰抽象方法。其子类只有实现抽象方法(通过添加方法体),才能产生实例。
抽象方法:规定子类应该具有的行为,但在抽象类尚且不能实现的方法,可以声明为抽象方法(提高代码的可扩展性)。
-
- 只有方法原型,没有方法体。
- 抽象方法的具体实现由子类在各自的类声明中完成。
- 只有抽象类可以包含抽象方法(观察有无abstract修饰)。
方法优点:隐藏具体的细节信息,子类使用相同的方法原型,包含了调用该方法时需要了解的全部信息;子类必须完成指定的行为。
abstract class Table { String str; abstract void WhatDoWeHave(); } class Computer extends Table{ String cmp = "computer"; @Override void WhatDoWeHave() { System.out.println("We have " + cmp + " on the table!"); } } class Screen extends Table { String scr = "screen"; @Override void WhatDoWeHave() { System.out.println("We have " + scr + " on the table!"); } } public class AbTest { public static void main(String[] args) { Computer cmp = new Computer(); Screen scr = new Screen(); cmp.WhatDoWeHave(); scr.WhatDoWeHave(); } }
封装:一种信息隐蔽技术
继承:基于已有类产生新类的机制
- 新类也称子类,通过继承,可以获得超类的属性和行为
- 在继承过程中,也可以获得超类的特性,包括方法和实例变量(可以直接调用)
- 子类可以修改继承的方法或者增加新的方法
单继承,一个子类只有单一的直接超类(java语言仅支持单继承)
abstract class Table { String str; protected int num; abstract void WhatDoWeHave(); } class Computer extends Table{ String cmp = "computer"; @Override void WhatDoWeHave() { System.out.println("We have " + cmp + " on the table!"); } } class Screen extends Table { String scr = "screen"; @Override void WhatDoWeHave() { System.out.println("We have " + scr + " on the table!"); } } public class AbTest { public static void main(String[] args) { Computer cmp = new Computer(); cmp.num = 2; Screen scr = new Screen(); scr.num = 1; cmp.WhatDoWeHave(); System.out.println("How many? " + cmp.num + "!"); scr.WhatDoWeHave(); System.out.println("How many? " + scr.num + "!"); } }
例子与上面的类似,在抽象类中补充num实例变量,在测试类中可以直接调用和设置。
继承的好处:有助于解决软件的可重用性问题,使程序结构清晰,降低了编码和维护的工作量。
多态:超类及其不同子类的对象可以相应同名的消息,具体的实现方法却不同;主要通过子类对超类方法的覆盖来实现。
- 超类对象和从相同的超类派生出来的多个子类的对象,可被当作同一种类型的对象对待;
- 实现同一接口不同类型的对象,可被当作同一种类型的对象对待;
- 可以向这些不同的类型对象发送同样的消息,由于多态性,这些不同类的对象响应同一个消息时的行为可以不同。
class Table { void Put() {} void Show() {} } class Computer extends Table { void Put() {System.out.println("I put a computer on the table!");} void Show() {System.out.println("We have a computer!");} } class Screen extends Table { void Put() {System.out.println("I put a screen on the table!");} void Show() {System.out.println("We have a screen!");} } public class PolyTest { public static void main(String[] args) { Table cmp = new Computer(); Table scr = new Screen(); cmp.Put(); cmp.Show(); scr.Put(); scr.Show(); } }
非常简陋的一个例子,大体意思就是子类覆盖了超类的方法。
在测试类中声明了子类的引用,并且对这些引用的实例对象调用超类中的方法,获得各自不同的输出。