2014-09-13 68 views
0

在C#或Java中,我如何才能創建一個只能使用實現的接口實例化的類?如何製作只能通過界面訪問的類?

對不起,如果這個問題之前問。

編輯:對不起,迷惑你,這個問題只是問出的好奇:

比如我有:

interface iA 
{ 
    int addNum(); 
} 

interface iB 
{ 
    int minusNum(); 
} 

class A implements iA, iB 
{ 
    private int A; 
    public int addNum() 
    { 
    A += 10; 
    return A; 
    } 

    public int minusNum() 
    { 
    A -= 10; 
    return A; 
    } 
} 

class TestIface 
{ 
    public static void main(String args[]) { 
    A testA = new A(); 
    iA testiA = new A(); 
    iB testiB = new A(); 

    testA.minusNum(); // No error, it has access to both methods 
    testA.addNum(); 

    testiA.minusNum();//ERROR 
    testiA.addNum(); 

    testiB.minusNum(); 
    testiB.addNum();//ERROR 
    } 
} 

我不知道是否有防止只是做開發的方式testA並訪問這兩種方法。

+0

沒有這樣的事情存在。 – 2014-09-13 16:05:22

+0

可能重複[如何實際使用Java接口?](http://stackoverflow.com/questions/504904/how-are-java-interfaces-actually-used) – user23123412 2014-09-13 16:06:09

+2

這樣做你會得到什麼? – 2014-09-13 16:06:57

回答

1

您可以使構造函數爲private,並定義一個創建新實例的靜態Create方法。

public interface ITest 
    { 
    } 
    public class A : ITest 
    { 
     private A() 
     { 
     } 
     public static ITest Create() 
     { 
      return new A(); 
     } 
    } 

然後創建類的實例的唯一途徑(!除了反思,但這是另一回事)是調用Create方法是這樣的:

ITest test = A.Create(); 
+0

那麼,爲什麼不呢:A test = A.Create(),測試仍然可以訪問大多數方法嗎? – Tr1et 2014-09-13 17:26:06

+0

你不能這樣做,因爲它給你一個編譯錯誤。將A.Create()結果作爲A的一個實例的唯一方法是通過顯式強制轉換。 – brz 2014-09-13 17:28:17

+0

@ Tr1et由於調用者只知道'A.Create'返回一個「ITest」的實例。 A.Create'的實現實際上返回一個'A'的實例是一個具有所示方法簽名的實現細節。 – 2014-09-13 17:49:08

3

如何使構造函數爲私有?

class A implements iA 
{ 
    public int returnNum() 
    { 
    return 10; 
    } 
    private A(){} 

    public static iA getInstance(){ 
    return new A(); 
    } 

} 
+1

代碼張貼是無用的(除非你的getInstance靜態) – 2014-09-13 16:08:13

+0

我編輯它..反正感謝它指向了:) – zerocool 2014-09-13 16:09:11

+0

這並不阻止其他人創造另一個具體實施的接口它使用公共構造函數,因此沒有填補OP的(不可能的)要求。 – 2014-09-13 16:09:40

0

你不能實例化東西通過一個接口。您只能將其聲明爲接口。如果你的目標是使addNum只能通過iAminusNum只能通過iB訪問的訪問,你可以嘗試顯式接口實現(儘管它有其自身的缺點):

class A : iA, iB 
{ 
    private int A; 

    int iA.addNum() 
    { 
     A += 10; 
     return A; 
    } 

    int iB.minusNum() 
    { 
     A -= 10; 
     return A; 
    } 
} 

這將至少給你編譯時的效果您正在尋找:

class TestIface 
{ 
    public static void main(String args[]) { 

     A testA = new A(); 
     testA.minusNum(); // does not compile 
     testA.addNum(); // does not compile 

     iA testiA = new A(); 
     testiA.minusNum();//does not compile 
     testiA.addNum(); 

     iB testiB = new A(); 
     testiB.minusNum(); 
     testiB.addNum();//does not compile 
    } 
} 

然而,這並不意味着addNum僅通過訪問一個變量是聲明iA。爲了說明這一點,你可以這樣做:

A testObj = new A(); 
(testObj as iA).addNum(); // this will compile 

你甚至可以這樣做:

iB testObj = new A(); 
(testObj as iA).addNum(); // this will also compile, and execute fine 

如果您想進一步防止明確鑄造往返於具體的類,你需要有采取勸告別人已經提出:使你的具體類一個嵌套的私有類,並引進一個工廠,生產實例:

class Factory 
{ 
    private class A : iA, iB 
    { 
     int iA.addNum() {...} 
     int iB.minusNum() {...} 
    } 

    public iA GetInstanceOfiA() 
    { 
     return new A(); 
    } 

    public iB GetInstanceOfiB() 
    { 
     return new A(); 
    } 
} 

這仍然沒有阻止91A的鑄造1B,我猜你必須創建兩個獨立的具體類來迎合。

+0

謝謝你,我驚訝的是它能夠寫出這樣的方法:iA.addNum(),它是唯一的Java或可用於C#嗎? – Tr1et 2014-09-16 06:33:43

+0

它是C#特有的。在StackOverflow或Goggle上搜索「顯式接口實現」會給出很多示例 – Xinchao 2014-09-16 10:53:27