java学习笔记7--抽象类与抽象方法
接著前面的學習:
java學習筆記6--類的繼承、Object類
java學習筆記5--類的方法?
java學習筆記4--類與對象的基本概念(2)
java學習筆記3--類與對象的基本概念(1)
java學習筆記2--數(shù)據(jù)類型、數(shù)組
java學習筆記1--開發(fā)環(huán)境平臺總結
本文地址:http://www.cnblogs.com/archimedes/p/java-study-note7.html,轉載請注明源地址。
1、終結類與終結方法
被final修飾符修飾的類和方法,終結類不能被繼承,終結方法不能被當前類的子類重寫
終結類的特點:不能有派生類
終結類存在的理由:
安全: 黑客用來攪亂系統(tǒng)的一個手法是建立一個類的派生類,然后用他們的類代替原來的類
設計: 你認為你的類是最好的或從概念上你的類不應該有任何派生類
終結方法的特點:不能被派生類覆蓋
終結方法存在的理由:
對于一些比較重要且不希望子類進行更改的方法,可以聲明為終結方法。可防止子類對父類關鍵方法的錯誤重寫,增加了代碼的安全性和正確性
提高運行效率。通常,當java運行環(huán)境(如java解釋器)運行方法時,它將首先在當前類中查找該方法,接下來在其超類中查找,并一直沿類層次向上查找,直到找到該方法為止
final 方法舉例:
class Parent {public Parent() { } //構造方法final int getPI() { return Math.PI; } //終結方法 }說明:?getPI()是用final修飾符聲明的終結方法,不能在子類中對該方法進行重載?
2、抽象類
抽象類:代表一個抽象概念的類
-
沒有具體實例對象的類,不能使用new方法進行實例化
-
類前需加修飾符abstract
-
可包含常規(guī)類能夠包含的任何東西,例如構造方法,非抽象方法
-
也可包含抽象方法,這種方法只有方法的聲明,而沒有方法的實現(xiàn)
-
抽象類是類層次中較高層次的概括,抽象類的作用是讓其他類來繼承它的抽象化的特征
-
抽象類中可以包括被它的所有子類共享的公共行為
-
抽象類可以包括被它的所有子類共享的公共屬性
-
在程序中不能用抽象類作為模板來創(chuàng)建對象;
-
在用戶生成實例時強迫用戶生成更具體的實例,保證代碼的安全性
舉個例子:
將所有圖形的公共屬性及方法抽象到抽象類Shape。再將2D及3D對象的特性分別抽取出來,形成兩個抽象類TwoDimensionalShape及ThreeDimensionalShape
–2D圖形包括Circles、Triangles、Rectangles和Squares
–3D圖形包括Cube、Sphere、或Tetrahedron
–在UML中,抽象類的類名為斜體,以與具體類相區(qū)別:
?
抽象類聲明的語法形式為
abstract class Number {. . . }3、抽象方法
聲明的語法形式為:
public abstract <returnType> <methodName>(...);僅有方法頭,而沒有方法體和操作實現(xiàn),具體實現(xiàn)由當前類的不同子類在它們各自的類聲明中完成,抽象類可以包含抽象方法
需注意的問題:
-
一個抽象類的子類如果不是抽象類,則它必須為父類中的所有抽象方法書寫方法體,即重寫父類中的所有抽象方法
-
只有抽象類才能具有抽象方法,即如果一個類中含有抽象方法,則必須將這個類聲明為抽象類
- 除了抽象方法,抽象類中還可以包括非抽象方法
抽象方法的優(yōu)點:
-
隱藏具體的細節(jié)信息,所有的子類使用的都是相同的方法頭,其中包含了調用該方法時需要了解的全部信息
-
強迫子類完成指定的行為,規(guī)定其子類需要用到的“標準”行為
舉一個繪圖的例子:
各種圖形都需要實現(xiàn)繪圖方法,可在它們的抽象父類中聲明一個draw抽象方法
abstract class GraphicObject {int x, y;void moveTo(int newX, int newY) { . . . }abstract void draw(); }然后在每一個子類中重寫draw方法,例如:
class Circle extends GraphicObject {void draw() { . . . } } class Rectangle extends GraphicObject {void draw() { . . . } }舉一個例子:
首先定義一個抽象類:
abstract class Person {private String name; //具體數(shù)據(jù)public Person(String n) { //構造函數(shù)name = n;}public String getName() { //具體方法return name;}public abstract String getDescription(); //抽象方法 }下面通過抽象類Person擴展一個具體子類Student:
class Student extends Person {private String major;public Student(String n, String m) {super(n);major = m;}public String getDescription() { //實現(xiàn)抽象類中的getDescription方法return "a student majoring in " + major;} }通過抽象類Person擴展一個具體子類Employee:
class Employee extends Person {private double salary;private Date hireDay;public Employee(String n, double s, int year, int month, int day) {super(n);salary = s;GregorianCalendar calendar = new GregorianCalendar(year, month - 1, day);hireDay = calendar.getTime();}public double getSalary() {return salary;}public Date getDate() {return hireDay;}public String getDescription() { //實現(xiàn)抽象類中的getDescription方法return String.format("an employee with a salary of $%.2f", salary);}public void raiseSalary(double byPercent) {double raise = salary * byPercent / 100;salary += raise;} }測試程序如下:
public class javatest {public static void main(String[] args) {Person[] people = new Person[2]; people[0] = new Employee("Hary Hacker", 50000, 1989, 10, 1);people[1] = new Student("Maria Morris", "Computer science");for(Person p : people)System.out.println(p.getName() + ", " + p.getDescription());} }運行結果如下:
Hary Hacker, an employee with a salary of $50000.00
Maria Morris, a student majoring in Computer science
再舉一個例子:
先定義一個幾何抽象類GeometricObject:
import java.util.*; public abstract class GeometricObject {private String color = "write";private boolean filled;private Date dateCreated;//構造函數(shù)(protected類型)protected GeometricObject() {dateCreated = new Date();}protected GeometricObject(String color, boolean filled) {dateCreated = new Date();this.filled = filled;this.color = color;}public String getColor() {return color;}public void setColor(String color) {this.color = color;}public boolean isFilled() {return filled;}public void setFilled(boolean filled) {this.filled = filled;}public Date getDateCreated() {return dateCreated;}public String toString() {return "created on" + dateCreated + "\ncolor: " + color + " and filled: " + filled;}public abstract double getArea(); //抽象方法public abstract double getPerimeter(); //抽象方法 }定義一個具體類Circle繼承抽象類:
public class Circle extends GeometricObject{private double radius;public Circle() {}public Circle(double radius) {this.radius = radius;}public Circle(double radius, String color, boolean filled) {this.radius = radius;setColor(color); //繼承基類setFilled(filled); //繼承基類 }public double getRadius() {return radius;}public void setRadius(double radius) {this.radius = radius;}public double getArea() { //實現(xiàn)抽象類中的抽象方法getArea()return radius * radius * Math.PI;}public double getPerimeter() { //實現(xiàn)抽象類中的抽象方法getPerimeter()return radius * 2 * Math.PI;}}定義一個具體類Rectangle繼承抽象類:
public class Rectangle extends GeometricObject {private double width;private double heigth;public Rectangle() {}public Rectangle(double width, double heigth) {this.width = width;this.heigth = heigth;}public Rectangle(double width, double heigth, String color, boolean filled) {this.width = width;this.heigth = heigth;setColor(color);setFilled(filled);}public double getWidth() {return width;}public void setWidth(double width) {this.width = width;}public double getHeigth() {return heigth;}public void setHeigth(double heigth) {this.heigth = heigth;}public double getArea() {return width * heigth;}public double getPerimeter() {return 2 * (width + heigth);} }3、類的組合
面向對象編程的一個重要思想就是用軟件對象來模仿現(xiàn)實世界的對象,現(xiàn)實世界中,大多數(shù)對象由更小的對象組成
與現(xiàn)實世界的對象一樣,軟件中的對象也常常是由更小的對象組成,Java的類中可以有其他類的對象作為成員,這便是類的組合
組合的語法很簡單,只要把已存在類的對象放到新類中即可,可以使用“has a”語句來描述這種關系
例如,考慮Kitchen類提供烹飪和冷藏食品的功能,很自然的說“my kitchen 'has a' cooker/refrigerator”。所以,可簡單的把對象myCooker和myRefrigerator放在類Kitchen中。格式如下:
class Cooker{ // 類的語句 } class Refrigerator{ // 類的語句} class Kitchen{ Cooker myCooker;Refrigerator myRefrigerator; }一條線段包含兩個端點:
public class Point //點類 {private int x, y; //coordinatepublic Point(int x, int y) { this.x = x; this.y = y;}public int GetX() { return x; }public int GetY() { return y; } } class Line //線段類 {private Point p1,p2; // 兩端點 Line(Point a, Point b) { p1 = new Point(a.GetX(),a.GetY());p2 = new Point(b.GetX(),b.GetY());}public double Length() { return Math.sqrt(Math.pow(p2.GetX()-p1.GetX(),2) + Math.pow(p2.GetY()-p1.GetY(),2));} }組合與繼承的比較:
“包含”關系用組合來表達
如果想利用新類內部一個現(xiàn)有類的特性,而不想使用它的接口,通常應選擇組合,我們需在新類里嵌入現(xiàn)有類的private對象
如果想讓類用戶直接訪問新類的組合成分,需要將成員對象的屬性變?yōu)閜ublic
“屬于”關系用繼承來表達
取得一個現(xiàn)成的類,并制作它的一個特殊版本。通常,這意味著我們準備使用一個常規(guī)用途的類,并根據(jù)特定需求對其進行定制
舉個例子:
car(汽車)對象是一個很好的例子,由于汽車的裝配是故障分析時需要考慮的一項因素,所以有助于客戶程序員理解如何使用類,而且類創(chuàng)建者的編程復雜程度也會大幅度降低
class Engine { //發(fā)動機類public void start() {}public void rev() {}public void stop() {} } class Wheel { //車輪類 public void inflate(int psi) {} } class Window { //車窗類public void rollup() {}public void rolldown() {} } class Door { //車門類public Window window = new Window();public void open() {}public void close() {} } public class Car {public Engine engine = new Engine();public Wheel[] wheel = new Wheel[4];public Door left = new Door(),right = new Door(); public Car() {for(int i = 0; i < 4; i++)wheel[i] = new Wheel();}public static void main(String[] args) {Car car = new Car();car.left.window.rollup();Car.wheel[0].inflate(72);} }許多時候都要求將組合與繼承兩種技術結合起來使用,創(chuàng)建一個更復雜的類
舉個例子(組合與繼承舉例):
class Plate { //聲明盤子public Plate(int i) {System.out.println("Plate constructor");} } class DinnerPlate extends Plate { //聲明餐盤為盤子的子類public DinnerPlate(int i) {super(i);System.out.println("DinnerPlate constructor");} } class Utensil { //聲明器具Utensil(int i) {System.out.println("Utensil constructor");} } class Spoon extends Utensil { //聲明勺子為器具的子類public Spoon(int i) {super(i);System.out.println("Spoon constructor");} } class Fork extends Utensil { //聲明餐叉為器具的子類public Fork(int i) {super(i);System.out.println("Fork constructor");} } class Knife extends Utensil { //聲明餐刀為器具的子類public Knife(int i) {super(i);System.out.println("Knife constructor");} } class Custom { // 聲明做某事的習慣public Custom(int i) { System.out.println("Custom constructor");} } public class PlaceSetting extends Custom {//聲明餐桌的布置 Spoon sp; Fork frk; Knife kn; DinnerPlate pl;public 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);} }運行結果:
Custom constructor
Utensil constructor
Spoon constructor
Utensil constructor
Fork constructor
Utensil constructor
Knife constructor
Plate constructor
DinnerPlate constructor
PlaceSetting constructor
參考資料:
《java程序設計》--清華大學
作者:wuyudong 出處:http://www.cnblogs.com/wuyudong/總結
以上是生活随笔為你收集整理的java学习笔记7--抽象类与抽象方法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java学习笔记6--类的继承、Obje
- 下一篇: java学习笔记8--接口总结