如何禁止对象直接实例化

ggewt2td 2012-10-03 02:22:21
比如有两个类:
class A{
...
}

class B{
public static A createA();
}


类A不能直接实例化,如 A a = new A();
禁止象上面直接实例化,
而必须通过B的方法来创建A,
如:
A a = B.createA();

就是说:
A a = new A(); //不允许这样直接实例化
A a = B.createA(); //只能通过B来创建A


...全文
1874 65 打赏 收藏 转发到动态 举报
写回复
用AI写文章
65 条回复
切换为时间正序
请发表友善的回复…
发表回复
showjim 2012-11-07
  • 打赏
  • 举报
回复
引用 13 楼 sp1234 的回复:
编程以系统集成测试为原则,而不是以所谓的“封闭概念、个人洁癖”为原则。很多时候为了让程序可测,我们需要把private的方法定义修改为public的,仅仅是为了迎合自动化测试系统的需要。此时不用过度纠结于作用域定义,让我们看看测试工程能测试什么bug来?!
是的,有些时候(不是说要放纵)不能够纠结于private和public,否则很肯能是自讨苦吃,而且不一定能达到目的。
7ero 2012-10-11
  • 打赏
  • 举报
回复
public interface IA { ... }

private A : IA
{
public A() { ... }
...
}

public B
{
public IA CreateA()
{
//通过反射创建A
}
}

试试这样
leixf2016 2012-10-09
  • 打赏
  • 举报
回复
在设计模式中有相关的内容,有时间的话可以看看
leixf2016 2012-10-09
  • 打赏
  • 举报
回复
[Quote=引用楼主 的回复:]
比如有两个类:
class A{
...
}

class B{
public static A createA();
}


类A不能直接实例化,如 A a = new A();
禁止象上面直接实例化,
而必须通过B的方法来创建A,
如:
A a = B.createA();

就是说:
A a = new A(); //不允许这样直接实例化
……
[/Quote]

可以这么写:

public class A
{
private static A _A;
private A(){}
public static A CreateA()
{
_A = new A();
return _A;
}
}


调用方法: A a = A.CreateA();
DemonXHunter 2012-10-09
  • 打赏
  • 举报
回复
不觉得这个问题很2吗?
你的工厂方法为什么一定要定义在class B 里面呢? 为什么不直接定义在class A里面呢? 有谁说了工程的类型和被创建的类型必须是不同的类型呢? 没事多看看反编译的.net运行库。

如果要用class B来构造A对象,那么只能是B 和 A在一个assembly里面,A的构造是internal的。

如果你还非要把class B定义在另外一个assembly里面,而且还只能有B来构造A对象,那么抛开C#的语法来说,B所在的project肯定需要引用A的project, 而A也必然需要通过某种语法指定说自己只能被B创建,那么意味着A的project必须要引用B的project。A B project 互相引用,意味着什么?意味着他么之间互相耦合依赖,那么本来就应该合并为一个project,那么解决方案还是internal那种。

.net中工厂模式实现有若干种典型方式
1. class A定义构造为私有,由class自己提供静态方法创建实例。
2. class A为抽象,若干子类型B,C,D,E..都设置构造为internal,由A类或者第三方类型提供静态方法构造实例。
3. 相互关联的对象之间进行创建,比如IDBConnection创建IDBCommand,这种实际上是抽象类工厂模式,两个具体类型应该在同一个assembly,而且有可能并不禁止对象直接实例化。

至于反射之类的方法就没有意义了,对吗? B可以反射,C难道就不可以反射?
ggewt2td 2012-10-09
  • 打赏
  • 举报
回复
就是要建立作用域,
没有销售的产品,作用域在工厂里,归属于工厂
只能工厂使用,工厂可以“生产/加工/检测/作废...” 产品,
然后销售后,产品的作用域发生了变化,归属于购买者,购买者有权使用,而工厂反而没有权限使用。
可能不是直接销售,还会经过中间商,比如超市这种中间环节,

其实就是对象所有者发生改变,就是所有者的转移。
如果软件的对象设计,能象真实的工厂那么直接就好了,而不是绕来绕去的,
tianyaxiao 2012-10-09
  • 打赏
  • 举报
回复
class Test
{
private function __construct(){

}

}
ggewt2td 2012-10-09
  • 打赏
  • 举报
回复
不过还是感觉有点绕,
不能直接通过工厂来创建对象,
需要抽象,又得建继承,又得内联,

如果能简单的直接通过工厂创建就好了,而禁止直接实例化。

就象工厂的产品,需要经过销售流程才能拿出给别人用。
不能私自把产品拿出去用。

如果对象设计,能象工厂那么直接就好了,而不是绕来绕去。
ggewt2td 2012-10-09
  • 打赏
  • 举报
回复
很感谢,还有人回复,

26楼已经实现了,当时没仔细看。
其实要禁止直接实例化,只要做成接口或抽象就行了。
接口不能有实现,抽象可以有。

然后将一个具体的实现类继承接口或抽象类,
这个 继承类可以放在工厂里,这样工厂可以修改该抽象类的一些东西。

很抱歉,当初没仔细看,所以没给26楼分。
IT修补匠 2012-10-09
  • 打赏
  • 举报
回复
不知道这个 能不能帮助楼主解决问题
http://technet.microsoft.com/zh-cn/magazine/0tke9fxk(VS.90).aspx
ssqmsx 2012-10-08
  • 打赏
  • 举报
回复
http://msdn.microsoft.com/zh-cn/library/c5kehkcz.aspx
xuan.ye 2012-10-08
  • 打赏
  • 举报
回复
这个就是典型的“单例模式”
彭小草 2012-10-08
  • 打赏
  • 举报
回复
直接把A定义成抽象类就行了。
莫聆 2012-10-08
  • 打赏
  • 举报
回复
A如果设为私有类的话,就只能在加一个接口了,B类创建A但返回A的接口就行了。
晓风吹雾 2012-10-08
  • 打赏
  • 举报
回复
A.java

public class A {
private A() {
}
}


B.java

public final class B {
public static A createA() throws SecurityException, NoSuchMethodException,
IllegalArgumentException, InstantiationException,
IllegalAccessException, InvocationTargetException {
Constructor<A> constructor = null;
try {
Class<A> clazz = A.class;
constructor = clazz.getDeclaredConstructor();
constructor.setAccessible(true);
return constructor.newInstance();
} finally {
if (constructor != null) {
constructor.setAccessible(false);
}
}
}

public static void main(String[] args) throws InstantiationException,
IllegalAccessException, SecurityException, NoSuchMethodException,
IllegalArgumentException, InvocationTargetException {
System.out.println(B.createA().hashCode());
}
}
andy0618 2012-10-08
  • 打赏
  • 举报
回复
这也是我想问的

比如一辆汽车,class 汽车(){}
每辆车都有发动机,那么要写一个发动机的类 class 发动机(){}
我想通过汽车对象来得到一个发动机对象,
而不是直接创建发动机对象,如果我直接创建发动机实例对象,那么就不知道这个发动机是属于哪个汽车的。

所以我以前也有些需求。

当然也可以用接口,但这样就要写一个接口,写一个实现类。
伤寒泪 2012-10-08
  • 打赏
  • 举报
回复
去掉默认的构造函数
#blackheart 2012-10-08
  • 打赏
  • 举报
回复
放一个dll,A修饰为Internal
e251396 2012-10-04
  • 打赏
  • 举报
回复
可不可以使用接口来实现?
Durant111 2012-10-03
  • 打赏
  • 举报
回复
都是高手,多多指教!!!
加载更多回复(43)

110,534

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧