以前发过一贴,http://bbs.csdn.net/topics/390232441
不过感觉没有得到很好的解答,再问一次,比如有两个类:
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我这样做是有用途的,
因为A是通过代码生成器生成的,生成之后,A就不能再改了,
如果要改,只能通过B来改,比如B创建A对象,并初始化A的一些属性,也许我的思路不对,不知道大家有没有更好的解决方法?
比如我生成数据对象的增删改查方法,生成后就不能手工去改它,
只能通过代码生成器重新生成。
但如果生成的代码不满足业务,需要增加功能时,我就通过B类来扩展A的功能,然后调用A时,必须通过B来创建A,避免不经过B的初始化就调用A.
这个非常类似于工厂模式,但工厂模式通过反射,我又不想反射,反射影响效率,而且代码难写
不过感觉没有得到很好的解答,再问一次,比如有两个类:
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我这样做是有用途的,
因为A是通过代码生成器生成的,生成之后,A就不能再改了,
如果要改,只能通过B来改,比如B创建A对象,并初始化A的一些属性,也许我的思路不对,不知道大家有没有更好的解决方法?
比如我生成数据对象的增删改查方法,生成后就不能手工去改它,
只能通过代码生成器重新生成。
但如果生成的代码不满足业务,需要增加功能时,我就通过B类来扩展A的功能,然后调用A时,必须通过B来创建A,避免不经过B的初始化就调用A.
这个非常类似于工厂模式,但工厂模式通过反射,我又不想反射,反射影响效率,而且代码难写
A类是自动生成的,不能手工去改,
如果要扩展功能,只能通过别的方式去扩展,
而且外面要调用A,必须是扩展之后的A。
class A
{
private A() {}
}
或者使用静态类
static class
{
...
}
还有抽象类:
abstract class A
{
...
}
abstract class A //抽象类不能实例化
{
}
class B : A //在B中可以重写和修改A的方法满足自己的需求
{
public static A createA() { return (A)new B(); }//返回A类型 但是是B的实现
}不知道这样能不能满足你的需求!
“但如果生成的代码不满足业务,需要增加功能时,我就通过B类来扩展A的功能” 这句我不是很理解!
如果你的意思是给B增加方法 使用的时候是通过B来调用这没问题
但是如果你是通过给B增加方法,最终A来调用这个就有问题了!
除非使用扩展方法来实现 但是不优美 如果多了会使方法管理和逻辑很混乱
private A{
}}设置成私有的,看看这样应该没法在别的地方实例化它。
如果A不能修改,那你无法阻止new A()这种。
DataRowBuilder builder
)
public abstract class A
{
}
.net自带的,DataRow这个类。
DataRow的情况,和你描述的完全一致。
不能直接实例化,
只能通过DataTable.NewRow()来创建一个新的实例。通过参考DataRow类的语法,
还有相关类的,比如DataTable之类的相互关系,
能帮你更好的完善这一块的应用。
回四楼,举个例子,A类提供几个属性:
private FldName as string
private FldSize as string
private isemail as string
private rule as string其中的 FldName 和 FldSize 的值是通过代码生成器生成的,
而 isemail 和 rule 没办法生成,只能通过一个 B 类来初始化A,
就是 B 类会扩展 A 类的属性和方法,
然后创建A的实例,必须通过 B 来创建.
A不允许直接创建,如果直接创建A,那 isemail 和 size 就会没被初始化,不合要求.
很类似于15楼说的,DataRow 的结构是根据 DataTable的结构 复制而来,15楼说的,DataRow 是怎么实现的?
通过抽象也算是一种方法,但抽象还必须提供一个继承类,比较麻烦,不过也算是一种比较合理的方式,
DataRow 是如何实现的?谁能说一下,我也好了解下看是不是符合要求,
A类一个文件,B类一个文件,不知道part 修饰符可以实现不?我看IDE自动生成的界面和后台代码,都有 partial 修饰符,
IDE自动生成的代码,一般是不允许改的,而后台代码可以随意改,
和这个有点类似,
{
protected FldName as string
protected FldSize as string
}
class B : A
{
protected isemail as string
protected rule as string
}
直接用B替代A不行吗?为什么要CreateA?
class A
{
private A(){}
private static A a = null;
public static A GetA(){
if(A == null)
a = new A();
return a;
}
}
首先 要实例化对象就必须得调用构造函数。
要想不能直接实例化,可以把构造函数私有化,如private Singleton(){}然后对外公开一个方法来创建对象 如 public static Singleton GetInstance(){.......}
//最简单的单例
public class Singleton
{
private static Singleton instance;
private Singleton(){}
public static Singleton GetInstance()
{
if(instance==null)
{
instance=new Singleton();
}
return instance;
}
}
如果B继承A,那就变成替代了,替代很明显不合要求,
因为我可以由B来加工A类,也可以由C来加工A类,这个是很自由的,
但如果用继承,就必须得继承A所有的方法和属性,就会造成一个庞大的B类,而且B不仅可以加工A类,还可以加工A1类、A2类...如同工厂的一条生产线,可以生产不同的产品一样...所以不能使用继承。没有哪个工厂会让一条生产线继承一种产品。
B继承A,C也继承A有什么关系呢?B类很大有什么关系呢?
否则你得手工包装,重写所有需要的方法与属性,何必呢?如果你需要的是“加工”,那么针对的应该是接口,而不是类。
.net框架这些东西都是开源的,而且也有类似Reflector等工具,你可应该自己看。
但工厂不能直接拿图纸来生产,必须有实物才行,
A类就是一个实物,而不是接口,
B类这个工厂类,生产出A对象,
这个不能用继承,因为B类不仅生产A对象,还可能生产A1、A2、A3、等很多种类的对象,
难道都要继承这些类才行?
如果要个普通的工厂,要么用反射,要么自己写case。
如果要能对任意类真实扩展,也许只能用动态类型dynamic。
A的构造函数为protected这样不能直接实例化A,但子类中可进行A的实例化。
然后B继承A,createA中生成一个A的对象
代码如下
public class A
{
protected A(){}
}
public class B:A
{
public B(){}
public A createA()
{
return new A();
}
}
2、用普通的继承也不太可能,
如果类B中的方法返回类A的实例的话,那么类A的访问级别不可能小于类B的访问级别,
也就是B是public,A也必须是public的。
3、除了类B,如果类A不能被其它类直接实例化的话,又要保证2可以实现,
可以将类A的构造函数声明成受保护的,类B继承类A。
但是在类的CreateA函数中只能写“return (A)new B();”,不能写“return new A();”。
B属于一种加工性质的类,不能继承A,因为它不仅能生成A,也可能生成C,生成D...
如果用继承,那就都得继承这些类,很明显是不行的,而且C#也不支持多继承,
扩展A类的一些属性和方法,以及实例化A类,
B类相当于代理类,而A类相当于真正处理的类,但代理模式,不能返回A的实例,而是返回B类的实例,通过B类去调用A类的方法.我要求的是,A和B类没有任何耦合的,不能用继承,继承的话A和B就耦合在一起了,
也不能用代理,代理时,A类被封装在内部,外面无法直接得到A的实例,其实只是控制A类的 创建,要B来创建,创建后,A对象和B就没有任何关系了。
有意义啊,我的A类是通过代码生成器生成的,不能手工去改,
所以我另外建了一个B类,去改A类,然后外界要得到A的实例,必须是B改过后的实例。这个有点类似于设计模式里的 装饰模式,
B来装饰 A
因为我用代码生成器重新生成A后,直接就覆盖原来的文件,
所以要求A类不能有任何手工改动的代码,如果手工改动,下次重新生成,就会把改动的全部给覆盖了。所以我要求A是一个单独的文件,而B是另外一个文件,
B来装饰A类,或者叫修改A类,很奇怪,这是非常合理的要求,怎么就没人碰到过类似的呢?
{
protected A() { }
} class B
{
private class A1 : A { } private class A2 : A { } public static A CreateA(int n)
{
switch (n)
{
case 1:
return (A)new A1();
case 2:
return (A)new A2();
}
return null;
}
}
这样的话,A,A1,A2必须都实现一个相同的接口,否则,当你把A改为A1的时候,以前使用A定义的引用就都需要修改成A1,所以必须暴露给外面一个接口。这样如果希望把A,A1,A2作为装饰模式来使用的话就比较容易了。
return new A(new A1(new A2()));
1.interface MyInterface{
2. public void sayHello();
3.
4.}
5.
6.class A implements MyInterface{
7.
8. public void sayHello(){
9. System.out.println("hello A");
10. }
11.}
12.
13.class A1 implements MyInterface{
14.
15. public void sayHello(){
16. System.out.println("hello A1");
17. }
18.}
19.
20.class A2 implements MyInterface{
21.
22. public void sayHello(){
23. System.out.println("hello A2");
24. }
25.}
26.
27.class B{
28. public static MyInterface createA(){
29. return new A();
30. }
31.}
32.
33.public class MyTest
34.{
35. public static void main(String[] args)
36. {
37. MyInterface a = B.createA();
38. a.sayHello();
39. }
40.}
因为我用代码生成器重新生成A后,直接就覆盖原来的文件,
所以要求A类不能有任何手工改动的代码,如果手工改动,下次重新生成,就会把改动的全部给覆盖了。
public partial class A {
}