java interface問題
interface x
class a implements x
class b extends a
{
a a1=new b();
x x1=a; //這段應該會等於 x x1=new b(); 但是介面不是不可以繼承類別嗎? 為何這樣子可以寫
}
各位大大 所以
1. x x1=new b(); 這樣子不就是在interface new一個實體,但介面是不能有new的不是嗎?
2.還是說因為他的實體是new b();,不是interface x所以才可以這樣宣告?
首先感謝兩位大大的回答
那大大請問一下幫我看一下我這樣說有沒有錯
1. A a = new B(); X x1 = a;
這一句話也就代表X x1=new B();因為有繼承關係所以可以這樣指派
所以是說他的實體是 B 但是他最後會被轉型成X
2.那大大有辦法以我這個例子來講 『介面沒辦法NEW 實體』這句話的意思?
讓我可以分辨一下~
因為他前面有interface x{}; 那在後面有這樣宣告X x1=a; 如果他前面這個x不是介面那我懂它的意思是可以這樣宣告的 , 但是他前面是轉型成x介面 那不就代表的他X x1=a; 他有new到實體,但介面不能有new 這樣子不就有問題?
咖啡大大跟 9527大大聽你們這樣一講似乎我有點概念,老實說我是要考ocpjp但是物件導向的觀念有點不清楚 因為這種題目出蠻多的
正如9527大大所說的我是 『搞混new的意義』跟前面的型別跟new 後面的不一樣 要怎分辨
1.9527大大答案是x.a1();? 因為x裡面沒有a1()的方法? 只有x1()的方法, 但我就是不懂他前面的 interface x型別,所以他但是他X x = a; 後面的x=a;只是將a的東西放入到x裡面,並不是去新增一個interface實體所以不會產生new,也就是不會出錯。 但如果是X x1=new X()就會出錯,因為他去新增一個實體,解釋對嗎?
2.咖啡大大 ,
A a = new B(); //以A來看B實體
X x1 = a; //以X來看B實體,因為a"參考"的是B實體
那他前面的A 跟X 就是在看他裡面是否有num 跟xyz 因為a沒有xyz所以他不能夠呼叫xyz,只能夠呼叫num
那我統整一下下 interface x{void cube(); }
class a implements x {void cube2(){} void cube(){} }
class b extends a{ void cube3(){} }
A a=new B(); //在類別A裡面有一個a物件,裡面的東西是B類別的東西,所以他能夠存取X型別跟b型別裡面的東西,但是因為它是A型別所以會過濾掉cube3(); 方法 只能使用cube(); cube2();
X x1=a;//會等於X x1=new B(); //因為X為介面 ,所以不能改為X x1=new X(), 但是X x1=new B()這段只是將new b()東西參照到x1裡面,所以不算是再new 一個介面X,而X型別只是在判斷說他只能夠存取裡面cube();方法,不能夠存取 cube 2()跟cube 3()
我這樣解釋對嗎?
兩位大大可以出個比較容易混淆的題目 考一下我嗎? 這樣我才知道我到底會不會?
2 個解答
- 酗咖啡重症患者Lv 58 年前最佳解答
x x1=a;
這是多型的用法,不是繼承喔
介面不是不可以繼承類別嗎?
是沒錯,
例:
interface Xb extends Xa{
...略..
}
Xa 就一定是 interface
a a1 = new b();
x x1 = a;
這是多型,這裡只生成了一個物件實體(new b()),對同一個物件實體來說,雖然分別由 a1、x1 參考
可是用 a1 跟 x1 能做的事,可能會不一樣
例:
interface X{
cal(int i);
}
class A{
int num;
}
class B extends A implements X{
int temp;
cal(int i ){
...略...//這是實作 X 的 cal
}
}
那麼,假設我在另一個程式中
寫了
A a = new B();
X x1 = a;
是可以的
但 a.temp 則不可以
x1.num、x1.temp 也都不可以
雖然只生成了一個 B 的物件實體
但 a 要以 A 的標準來看,因為 a 是宣告為 A 型態
A 型態只有 num,沒有 temp,沒有 cal()
所以不能用 a.temp、a.cal(xxx) 但可以 a.num
同理,x1 就只有 cal 的方法就只能使用 :x1.cal(xxx)
若是
B b = x1;
因為生成的物件實體是 B,而 B 繼承了所以
b.num、b.temp、b.cal(xxx) 都可以使用
這是多型
A a = new B();
X x1 = a;
至於 x1 能不能 = a;
必須看實際生成的物件實體是否有符合 X 型態的標準
2012-10-23 08:13:15 補充:
介面是不能有new的不是嗎?
沒有錯;
x x1=new b();
new b();
實體就是 b;
x x1 只是宣告一個x型態的變數 x1
至於x1能不能指向(或許說參考)到 b 實體(就是 能不能等於 = (assign))
則必須看 b 實體符不符合 x 型態(就是有沒有繼承或是實作)
2012-10-25 08:02:51 補充:
生成實體指的是 new xxx()
介面沒辦法NEW 實體 是 xxx 不會是 介面,很直接單純
XX x1 = new XX();
這樣的語法,可分三部分(先不管前面型別)
1.等於左半邊
2.等於右半邊
3.等於 =
右半 是 生成實體(於記憶體中)
左半,它只是宣告一個名稱而已(只是對一個記憶體位置取名為 x1)
= 做的是:把實體在記憶體中的那個位址編號,記錄到 x1
所以
X x2 = x1;
所做的是
對一個記憶體位址取名 x2,把 x1 所記錄的值,記錄到 x2
(所以x2也記錄"實體在記憶體中的那個位址"),實體還是原實體XX
2012-10-25 08:19:59 補充:
而XX、X型別宣告則可以想成"過濾器",
A a = new B(); //以A來看B實體
X x1 = a; //以X來看B實體,因為a"參考"的是B實體
B是繼承A,A宣告了num,B宣告了 xyz;
B實體生成,同時有 num 跟 xyz (不考慮存取限制的話)
但以A來看B實體時,a.xyz是不存在的(因為A沒有宣告 xyx,即使B實體確實有xyz)
同理:
X x1 = a; //是用介面X來看B實體
只剩下 "x1.介面X有宣告的方法" 能用
- 8 年前
你應該把interface用型別來看。
我把你的範例改成用生活範例的說法。
interface 動物 (宣告一個動物的介面)
class 鳥類 implements 動物 (指鳥類是動物的一種)
class 麻雀 extends 鳥類 (指麻雀是鳥類的一種)
使用時...
動物 a =new 麻雀();//此時可以說,麻雀是動物的一種
鳥類 x1= a; //在這裡也可以說麻雀是鳥類的一種
你的疑問應該是,為什麼 鳥類(class) 實做了 動物(interface)後,
還可以被 麻雀(class)繼承呢?
在此,鳥類雖實做了動物的interface,
鳥類(class)並不會變成interface,
只能說:鳥類屬於動物的一種。
所以麻雀(class)可以繼承鳥類(class)是正常的。
但是,
麻雀(class)繼承動物(interface)這樣就會發生錯誤,
除非你將動物(interface)改成抽象物件。
建議你可以上網找找抽象物件和介面的差異,
因為用打字的會打太多.....
而樓上所說的多型也是錯誤的
x x1=a; 此動作不是多型。
多型的範例應該由下列這樣(懶得打字,直接打範例)
//假如動物的interface有一個移動(move)的方法
interface 動物 {
public void move();
}
此時
麻雀、狗、貓的class都有實做動物這個interface
使用上便可這樣...
動物 a1 = new 麻雀();//建立一個麻雀的物件
動物 a2 = new 狗();//建立一個狗的物件
動物 a3 = new 貓();//建立一個貓的物件
//看起來都叫移動,但內容卻不相同
a1.move();//麻雀移動時可能用飛的
a2.move();//狗移動時用走的
a3.move();//貓移動時用走的
2012-10-24 10:29:51 補充:
interface不能new成一個實體,
是因為他裡面的方法都是抽象方法,
因為interface跟本沒有實做成方法,
所以就算給你new好了,
你也不能用阿....
2012-10-24 16:21:32 補充:
關於你的問題:
但是他前面是轉型成x介面 那不就代表的他X x1=a;
他有new到實體,但介面不能有new 這樣子不就有問題?
實際上你有點搞混new的意義了。
介面不能new應該是這樣:X x1 = new X();
new的意義是指依你所定義的class產生物件。
X x1=a; 只是把a的物件參考到X的介面,
但並不影響a這個物件。
2012-10-24 16:23:41 補充:
我這裡問你一個基本觀念的問題
Interface X {
public void x1();
}
class A implements X{
public void a1() {}
public void x1() {};
public static void main(String[] xxxxx) {
A a = new A();
X x = a;
//你覺得下面四個呼叫方法那一個會錯呢?
a.a1();
a.x1();
x.a1();
x.x1();
}
}