繼承和組合的概念
成都創(chuàng)新互聯(lián)堅持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:網(wǎng)站制作、做網(wǎng)站、企業(yè)官網(wǎng)、英文網(wǎng)站、手機端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿足客戶于互聯(lián)網(wǎng)時代的武義網(wǎng)站設(shè)計、移動媒體設(shè)計的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!
在新類里簡單地創(chuàng)建原有類的對象 我們把這種方法叫作 組合 因為新類由現(xiàn)有類的對象合并而成 我們只是簡單地重復(fù)利用代碼的功能 而不是采用它的形式
第二種方法是創(chuàng)建一個新類 將其作為現(xiàn)有類的一個 類型 我們可以原樣采取現(xiàn)有類的形式 并在其中加入新代碼 同時不會對現(xiàn)有的類產(chǎn)生影響 這種魔術(shù)般的行為叫作 繼承 (Inheritance) 涉及的大多數(shù)工作都是由編譯器完成的 對于面向?qū)ο蟮某绦蛟O(shè)計 繼承 是最重要的基礎(chǔ)概念之一 對于組合和繼承這兩種方法 大多數(shù)語法和行為都是類似的(因為它們都要根據(jù)現(xiàn)有的類型生成新類型)
組合也就是一個類的對象是另外一個類的成員 一般的程序都有組合的意味 只不過是基本數(shù)據(jù)類型是成員變量 下面請看具體的例子
class Head
{
Head(){
System out println( head );
}
}
class Body
{
Body(){
System out println( body );
}
}
class Person()
{
Head h=null;
Body b=null;
Person()??????????????????????????????? //人是由頭和身體組成的 Head和Body的對象是Person的一部分
{
h=new Head();
b =new Body();
}
}
繼承作為面向?qū)ο蟮娜齻€重要特性的一個方面 在面向?qū)ο蟮念I(lǐng)域有著及其重要的作用 好像沒聽說哪個面向?qū)ο蟮恼Z言不支持繼承
class Person
{
private String name=null;
private int age= ;
public Person(String n int a)
{
name=n;
age=a;
}
int getAge()
{
return age;
}
String getName()
{
return name;
}
void getDescription()
{
System out println( name: +name+ \t + age: +age);
}
}
class Student extends Person
{
private String studno=null;
public Student(String n String no int a)
{
super(n a);
studno=no;
}
}
說明:Student類中有三個成員變量name age studno和一個方法getDescription();
注意:子類繼承了父類的所有變量和函數(shù) 只是子類不能訪問父類的private類型的變量和函數(shù) 其實privae類型的變量還是繼承到子類中的
無論還是繼承 都允許我們將子對象置于自己的新類中 大家或許會奇怪兩者間的差異 以及到底該如何選擇
如果想利用新類內(nèi)部一個現(xiàn)有類的特性 而不想使用它的接口 通常應(yīng)選擇組合 也就是說 我們可嵌入一個對象 使自己能用它實現(xiàn)新類的特性 但新類的用戶會看到我們已定義的接口 而不是來自嵌入對象的接口 考慮到這種效果 我們需在新類里嵌入現(xiàn)有類的private對象
有些時候 我們想讓類用戶直接訪問新類的組合 也就是說 需要將成員對象的屬性變?yōu)閜ublic 成員對象會將自身隱藏起來 所以這是一種安全的做法 而且在用戶知道我們準備合成一系列組件時 接口就更容易理解 car(汽車)對象便是一個很好的例子
class Engine {
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[ ];
public Door left = new Door()
right = new Door(); // door
Car() {
for(int i = ; i ; i++)
wheel[i] = new Wheel();
}
public static void main(String[] args) {
Car car = new Car();
car left window rollup();
car wheel[ ] inflate( );
}
} ///:~
由于汽車的裝配是故障分析時需要考慮的一項因素(并非只是基礎(chǔ)設(shè)計簡單的一部分) 所以有助于客戶程序員理解如何使用類 而且類創(chuàng)建者的編程復(fù)雜程度也會大幅度降低
如選擇繼承 就需要取得一個現(xiàn)成的類 并制作它的一個特殊版本 通常 這意味著我們準備使用一個常規(guī)用途的類 并根據(jù)特定的需求對其進行定制 只需稍加想象 就知道自己不能用一個車輛對象來組合一輛汽車——汽車并不 包含 車輛 相反 它 屬于 車輛的一種類別 屬于 關(guān)系是用繼承來表達的 而 包含 關(guān)系是用組合來表達的
protected
現(xiàn)在我們已理解了繼承的概念 protected這個關(guān)鍵字最后終于有了意義 在理想情況下 private成員隨時都是 私有 的 任何人不得訪問 但在實際應(yīng)用中 經(jīng)常想把某些東西深深地藏起來 但同時允許訪問衍生類的成員 protected關(guān)鍵字可幫助我們做到這一點 它的意思是 它本身是私有的 但可由從這個類繼承的任何東西或者同一個包內(nèi)的其他任何東西訪問 也就是說 Java中的protected會成為進入 友好 狀態(tài)
我們采取的最好的做法是保持成員的private狀態(tài)——無論如何都應(yīng)保留對基 礎(chǔ)的實施細節(jié)進行修改的權(quán)利 在這一前提下 可通過protected方法允許類的繼承者進行受到控制的訪問
import java util *;
class Villain {
private int i;
protected int read() { return i; }
protected void set(int ii) { i = ii; }
public Villain(int ii) { i = ii; }
public int value(int m) { return m*i; }
}
public class Orc extends Villain {
private int j;
public Orc(int jj) { super(jj); j = jj; }
public void change(int x) { set(x); }
} ///:~
可以看到 change()擁有對set()的訪問權(quán)限 因為它的屬性是protected(受到保護的)
再論合成與繼承
lishixinzhi/Article/program/Java/hx/201311/26635
重載wolf1的構(gòu)造函數(shù)使其接受一個animal的實例,是為了外界代碼傳入animal實例,方便調(diào)用。如果你直接new一個animal實例的話,在實際開發(fā)中一般都不現(xiàn)實,因為這樣就寫死了,如果animal實例類中還有很多數(shù)據(jù)字段(比如從數(shù)據(jù)庫中加載)的話
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
// 創(chuàng)建Scanner對象,用于獲取用戶輸入
Scanner scanner = new Scanner(System.in);
System.out.print("請輸入任意字符序列:");
// 獲取用戶輸入的字符序列
String str = scanner.nextLine();
// 循環(huán)遍歷字符序列中的每個字符
for (int i = 0; i str.length(); i++) {
// 獲取字符序列中的第i個字符
char c1 = str.charAt(i);
// 循環(huán)遍歷字符序列中的每個字符
for (int j = 0; j str.length(); j++) {
// 獲取字符序列中的第j個字符
char c2 = str.charAt(j);
// 如果第i個字符不等于第j個字符,則輸出它們的排列
if (i != j) {
System.out.println(c1 + "" + c2);
}
}
}
}
}