Q:程式中A句執行個體化了抽象類別OutputStream 怎麼回事?抽象類別不是不能執行個體化的嗎?
import java.net.*; import java.io.*; public class TCPClient { public static void main(String[] args) throws Exception { Socket s = new Socket("222.91.106.117", 6666); OutputStream os = s.getOutputStream(); // A DataOutputStream dos = new DataOutputStream(os); dos.writeUTF("LJ be bravery!"); dos.flush(); dos.close(); s.close(); }}
A:A句並沒有執行個體化了抽象類別OutputStream
OutputStream os 只是聲名一個類型為OutputStream 變數
s.getOutputStream(); 是擷取一個抽象類別OutputStream 的執行個體對象
基礎最重要 好好看一下基礎
Q:String urlStr = "http://dict.baidu.com/";
URL url = new URL(urlStr);
URLConnection con = url.openConnection();
int contentLength = con.getContentLength();
URLConnection在API中定義為public abstract class URLConnectionextends Object
A:URLConnection為抽象類別表示本身不能被執行個體化,即:URLConnection uc= new URLConnection();這就是一種錯誤的寫法,但是URLConnection有兩個子類:HttpURLConnection和JarURLConnection , url.openConnection()方法返回肯定就是這兩個子類中的一個,這是java多態性的一種體現,想必樓主應該可以相通了吧!
Q:抽象類別 URLConnection 是所有類的超類,它代表應用程式和 URL 之間的通訊連結。此類的執行個體可用於讀取和寫入此 URL 引用的資源。這是API上寫的 為什麼說此類的執行個體?
A:java的多態性就是體現在用一個父類聲明,可以執行個體化其子類對象!我舉個例子:譬如:
abstract class Person{....} class Student extends Person{...},表明這個Student類繼承了抽象類別Person,我們在程式中可以這麼聲明:Person p = new Student();這裡就是用父類聲明,執行個體化其子類對象,這個Student對象也能說成是抽象類別Person的執行個體。不知道這麼說你可理解了!
抽象類別的建構函式
1、抽象類別是可以有建構函式的。但很多人認為,建構函式用於執行個體化一個對象(或建立一個對象的執行個體),而抽象類別不能被執行個體化,所以抽象類別不應該有公用的建構函式(FxCop.設計規則)。但不應該有“公用”的建構函式,和不應該有建構函式,這是兩個不同的概念,所以,FxCop.設計規則中也說,如果抽象類別需要建構函式,那麼應該聲明為“protected”。
2、既然抽象類別是可以,甚至有時候應該有建構函式,那抽象類別的建構函式的作用是什嗎?我覺得至少有兩個:
(1)初始化抽象類別的成員;
(2)為繼承自它的子類使用。
比如以下例子:
public abstract class Component{ protected string name; public Component(string name) { this.name = name; } public abstract void Add(Component component); public abstract void Remove(Component component); }public class Composite : Component{ private List<Component> children = new List<Component>(); public Composite(string name) : base(name) { } public override void Add(Component component) { this.children.Add(component); } public override void Remove(Component component) { this.Remove(component); } }
3、即使我們聲明一個沒有建構函式的抽象類別,編譯器還會為我們產生一個預設的保護層級的建構函式。子類執行個體化時(不管是否為帶參構造)只會調用所有父類的無參建構函式,而帶參構造必須通過顯式去調用.調用順序是先調用抽象類別的無參建構函式,如果子類執行個體化時是使用帶餐的建構函式,則再接著調用抽象類別的帶參建構函式,最後調用子類本身的建構函式。