读书人

[共400分+来者有分+]怎么实现类的不同

发布时间: 2012-02-13 17:20:26 作者: rapoo

[共400分+来者有分+求助]如何实现类的不同构造函数拥有不同的方法?
我的问题是:
比如:
public class a
{
private int _Id;

//构造函数
public a()
{

}

public a(int paramInt)
{
this._Id=paramInt
}

public int UpDate()
{
//其他代码
/*我的目的:我想在使用这个类的时候,a=new a();这个时候只能使用Update()这个方法,而下面这个Delete()方法不能使用.(最好是在a点的时候智能提示不显示Delete()这个方法.*/
}
public int Delete()
{
  //其他代码
/*我的目的:我想在使用这个类的时候,a=new a(1);这个时候只能使用Delete()
这个方法,而上面那个UpDate()方法不能使用.(最好是在a点的时候智能提示不显示UpDate()这个方法.*/

}
}


简单的说:
就是:
如果使用a=new a()实例化的时候,只能使用UpDate()方法(最好是在a点的时候智能提示不显示Delete()这个方法).

如果使用a=new a(1)实例化的时候,只能使用Delete()方法(最好是在a点的时候智能提示不显示UpDate()这个方法).

不知道可以实现不呢?

请各位大哥大姐帮帮忙,3Q!


还有我发个一个同样的帖子200分:
http://community.csdn.net/Expert/topic/5649/5649429.xml?temp=.1706964


来者有分哈!

[解决办法]
曲线救国


public class A
{
private int _Id;
private A _A = null;

public A()
{
_A = new A1();
}

public A(int paramInt)
{
this._Id = paramInt;
_A = new A2(paramInt);
}

public int UpDate()
{
if (_A is A2)
{
throw new Exception( "Update方法不能用 ");
}
}

public int Delete()
{
if (_A is A1)
{
throw new Exception( "Delete方法不能用 ");
}
}
}

public class A1 : A
{
}

public class A2 : A
{
}
[解决办法]
大家都来探讨阿!
[解决办法]
怎么没人呢?

[解决办法]
每个都建类
[解决办法]
类似这样

public a()
{
a(true);
}

public a(bool create)
{
if (create)
UpDate();
else
Delete();
}
[解决办法]
构造函数重载
通过设置不同参数对构造函数重载
比如public a()
{}
也可以
public a(string str1)
{}
还可以public a(string str1, int i)
{}
etc..

[解决办法]
帮顶!
[解决办法]
那你在写够造函数的时候,给UpDate()不带参数,给Delete()带一个int i 的参数可以不,
就是这样
public int UpDate(){}

public int Delete(int i){}


[解决办法]

[解决办法]
Class1 sd = new Class1(true);
Response.Write(sd.Delete());

-------------------------



Class1 sd = new Class1();
Response.Write(sd.Delete());


string asd= " ";
public Class1()
{
Class1 cl = new Class1(true);
asd = "ppp ";
}

public Class1(bool create)
{
if(create)
asd = "1111 ";
}

public string Delete()
{
return asd;
}

返回的不同可以分别写两个方法在两个构造函数里面
[解决办法]
mark
[解决办法]
学习!
[解决办法]
这种想法本身好象就不合理,如果实例化后的两个对象有不同的方法,不同的特性,那就应该是两个类,如果有相同的方法,就都继承父类,如果有相同的方法签名,就提取出来接口。
[解决办法]
楼上说的都不错,也都可实现
但楼主写的这个类似乎只能自己用,别人用时怎么知道如何调用Delete()方法呢?


[解决办法]
接分了
[解决办法]
定义不同参数的构造函数是可以,但是你要在同一个类的不同实例里面把不同函数屏蔽掉好像不能吧,要么定义成两个类。
[解决办法]
mapserver(杨东 http://mapserver.cnblogs.com)

学习了,设置一个标致是最简单,也是最容易理解的.
顶上去~
[解决办法]
不符合设计的原则 多此一举
[解决办法]
两个函数既然在类里定义了,编译的时候就一定会放入二进制代码中(系统自动优化掉无意义函数除外)

比较赞成mapserver(杨东 http://mapserver.cnblogs.com)
写的那个

要想不编译进去只有用
#if
...
#else
...
#end

C#应该也用类似的东东吧
[解决办法]
public class a
{
private int _Id;

//私有构造函数
private a()
{

}

public a(int paramInt)
{
this._Id=paramInt
}

//实例方法
public int Update(string name , int age)
{
//类似update table set col_name=name and col_age=age
}
//静态方法
public static int Delete(int id)
{
  //类似delete from table where col_id = id
}
}

[解决办法]
如果解释型,有什么办法
[解决办法]
我要向你请教
[解决办法]
来慢了~~要讲的上都讲过了
[解决办法]
up
[解决办法]
这样很难实现啊,不如在delete update里面判断
不过你这样的设计并不符合面向对象思想
[解决办法]
向楼上一样一个写成静态函数,一个写成非静态,一个直接从类调用,一个实例化调用可可以区分开来
[解决办法]
1。
可以确定的是实际场景中存在这样的设计需求:

2。
基本就是 mapserver 的做法了:运行时,判断当前类型是否支持调用方法。如果不支持,丢出异常。

3。
当然,你可以不用 is 运算。根据不同的需求类设计,采取不同的策略,比如提供一个标志或者重写基类方法。

下面,看看我之前比较留意到的 .net 类库中关于 可写集合类 与 只读集合类的设计

4。非泛型版本
System.Collections.ArrayList 这是一个可读写的集合类

System.Collections.ReadOnlyArrayList 这是一个只读的集合类,此类直接继承 System.Collections.ArrayList,并且作为 ArrayList 的

一个内嵌类,只读也就意味着使用者调用 Add Remove 方法是无效,但是其确实具有 Add Remove 方法,因为他继承了 ArrayList

// ArrayList 类


public class ArrayList : IList, ICollection, IEnumerable, ICloneable
{
// ...
// 常规的 Add 实现
public virtual int Add(object value)
{
if (this._size == this._items.Length)
{
this.EnsureCapacity(this._size + 1);
}
this._items[this._size] = value;
this._version++;
return this._size++;
}
// ....

private class ReadOnlyArrayList : ArrayList
{
// ...
// 重写基类的方法,直接丢出不支持的异常,但是只有当运行时才知道
public override int Add(object obj)
{
throw new NotSupportedException(Environment.GetResourceString( "NotSupported_ReadOnlyCollection "));
}
// ...
}
}

}

看看使用场景:

// 可写版本
System.Collections.ArrayList list1 = new System.Collections.ArrayList();
// inert item, OK
list1.Add( "a ");
list1.Add( "b ");
list1.Add( "c ");
// 只读版本
System.Collections.ArrayList list2= System.Collections.ArrayList.ReadOnly(list1);
Response.Write(list1.IsReadOnly); // false;
Response.Write(list2.IsReadOnly); // true;
// try insert item, failed
// list3.Add( "Cant insert an item into the ReadOnlyArrayList "); // wrong, throw System.NotSupportedException: 集合是

只读的。


这里 ArrayList 与 ReadOnlyArrayList 从类定义角度上看,他们均是一个“表示使用大小可按需动态增加的数组”,数据与行为上是一致的

,只是说,ReadOnlyArrayList 的“行为”有点的不完整的类。
就像某个残疾人,他又可能失聪,又可能聋,又可能哑,但是他依然可以吃饭,可以睡觉,只是某方面残缺,当你让他执行他所无法完成的功

能,他可能“抱怨”。但是他完完全全是人,跟正常人一样。
这个类比很不恰当,我一时没有想到更好的类比,我表示歉意。希望各位身有残疾的朋友谅解,没有必要心里存在疙瘩!

5。泛型版本
System.Collections.Generic.List <T>

System.Collections.ObjectModel.ReadOnlyCollection <T>

注:事实上,存在一个非泛型版本的 System.Collections.ReadOnlyCollectionBase,4 中我们用
ArrayList 与 ReadOnlyArrayList ,是因为他们更相似,更复合我们这里讨论的场景,
而这里,选择 List <T> 与 ReadOnlyCollection <T> , 同样的原因,看看下面的伪代码,就知道,实际上这两个类的行为应该是完全一样,他

们实现了一致的接口

public class List <T> : IList <T> , ICollection <T> , IEnumerable <T> , IList, ICollection, IEnumerable
{
// ...
// 常规的 Add 方法
// 采取隐式接口实现 ICollection <T> .Add 方法
public void Add(T item)
{
if (this._size == this._items.Length)
{
this.EnsureCapacity(this._size + 1);
}
this._items[this._size++] = item;
this._version++;
}
// ...
}

public class ReadOnlyCollection <T> : IList <T> , ICollection <T> , IEnumerable <T> , IList, ICollection, IEnumerable
{
// ...
//
// 采取显式接口实现 ICollection <T> .Add 方法
void ICollection <T> .Add(T value)
{
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
// ...
}

看看使用场景:

// 可写版本
System.Collections.Generic.IList <string> _list1 = new System.Collections.Generic.List <string> ();
// insert item, ok
_list1.Add( "a ");
_list1.Add( "b ");
_list1.Add( "c ");
// 只读版本
System.Collections.ObjectModel.ReadOnlyCollection <string> _list2 = new

System.Collections.ObjectModel.ReadOnlyCollection <string> (_list1);
Response.Write(_list1.IsReadOnly); // false;
// Response.Write(_list2.IsReadOnly); // error: CS0117: “System.Collections.ObjectModel.ReadOnlyCollection <string> ”

并不包含“IsReadOnly”的定义
Response.Write(((System.Collections.Generic.ICollection <string> )_list2).IsReadOnly); // true


// _list2.Add( "Cant insert an item into the ReadOnlyCollection <T> "); // error, CS0117:

“System.Collections.ObjectModel.ReadOnlyCollection <string> ”并不包含“Add”的定义
// ((System.Collections.Generic.ICollection <string> )_list2).Add( "Cant insert an item into the

ReadOnlyCollection <T> "); // wrong, System.NotSupportedException: 集合是只读的。


6。
我们看到, ReadOnlyCollection <T> 对于不支持的行为采取了显示接口的实现,显示接口实现的方法某种成度上,具有“私有实现”的效果,因为你只有强制转换为目标接口类型,才可以消费其行为。

这种场景下,刚好满足 LZ 要求的 “最好是在a点的时候智能提示不显示UpDate()这个方法。”,因为 ReadOnlyCollection <T> 中实现的 Add 方法实际上是属于接口 ICollection <T> 的
当然,这种效果实际上,你完全可以在 IDE 的“智能感应”功能上做“手脚”,比如的“智能感应”可以实现对具有某种 Attribute(特性) 的方法、属性等类成员不“感冒”。

7。
我个人以为,类库设计、框架设计的功力,不是一朝一夕能够练就的,需要具备相当深厚的功底,丰富的实践经验。
我个人在实现的时候,常常对自己的代码产生怀疑,总觉得设计的出来类,不伦不类。
条条道路同罗马,没有绝对的答案。完全跟着需求走,当然,每个人的功力也是在不段的进步。

事实上,我们经常发现, .net framework 中也又很多设计的不得合理的地方,更确确的说,应该是没有经得实践的“考验”,
比如,在 1.x 中,MSND 建议我们实现自己的异常,应该继承自 ApplictionException, 而实际上 .net 内部就没有遵循此规则,
而且,实践证明,继承 ApplictionException 并没有带来什么明白的优势, 现在 2.0 就建议直接继承 Expcetion 了

还有我在一个偶然的机会发现,System.Windows.Forms.FormCollection 继承自 System.Collections.ReadOnlyCollectionBase,但是
FormCollection 却实现了 Add 方法,当然此方法的访问修饰符是 internal ,即只有MS自己程序集才可以访问,
因为我基本没有WinForm开发的实践经验,也没有体会这样设计的用意,觉得 MS 自己也采取一种“投机取巧”的方法 ^_^



[解决办法]
没道理
[解决办法]
潜力帖!
[解决办法]
winform的开发投机取巧的东西多了,用reflection看微软的类库的源代码里面很多东西都很实现得很有技巧。。
[解决办法]
只为学习而来。。
[解决办法]
帮顶
[解决办法]
用接口做,可以解决了
[解决办法]
ding
[解决办法]
大家继续努力!
[解决办法]
可以试下接口~
[解决办法]
学习

[解决办法]
weizhuangzhi(壮志 ☆☆☆☆☆)

这种想法本身好象就不合理,如果实例化后的两个对象有不同的方法,不同的特性,那就应该是两个类,如果有相同的方法,就都继承父类,如果有相同的方法签名,就提取出来接口。



同意
我感觉lz的设计不太合理
建议可以看一下书中关于类的地方
lz的想法应该可以如weizhuangzhi所说方面实现
[解决办法]
up
[解决办法]
学习
[解决办法]
帮忙顶,接分
[解决办法]
感觉你要的要求超出语言所能处理的范畴,不过类似的效果可以实现
public interface IBaseTest
{
void Execute();
}

public class Child1 : IBaseTest
{

#region IBaseTest 成员

public void Execute()
{
Console.WriteLine( "这里填写Update实现方法 ");
}

#endregion
}

public class Child2 : IBaseTest
{

#region IBaseTest 成员

public void Execute()


{
Console.WriteLine( "这里填写Delete实现方法 ");
}

#endregion
}

public enum Type
{
Update,
Delete
}

public class Factory
{
private IBaseTest obj;

public IBaseTest Ojb
{
get { return obj; }
}

private Factory()
{
this.obj = new Child1();
}

public Factory(Type type)
{
switch (type)
{
case Type.Update:
this.obj = new Child1();
break;
case Type.Delete:
this.obj = new Child2();
break;
}
}
}

/// <summary>
/// 调用
/// </summary>
public class Client
{
public void Delete()
{
new Factory(Type.Delete).Ojb.Execute();
}

public void Update()
{
new Factory().Ojb.Execute();
}
}
代码是随手写的,可能编译不过,仅仅演示实现方法。
如果把实现类作为内联类,可能更像你要的东东
o(∩_∩)o
记得给分哟
[解决办法]
纯学习~~
[解决办法]
是不是想过太多了?如果是同个类,怎么能一会儿有某些方法,一会儿又显示另外的方法呢?

如果这个类有2个职责,根据单职责原则,是不是应该把它变成2个类或者把职责分成2个接口?

interface IUpdater
{
public void Update();
}

interface IDeleter
{
public void Delete();
}

public class a : IUpdater, IDeleter
{
//...
}

class Factory
{
public IUpdater Create() {...}
public IDeleter Create(int i) {...}
}
[解决办法]
你们为什么4点还没睡,作程序难到真有传说中的这么苦吗
[解决办法]
留名
[解决办法]
终于看到思归了!!!
[解决办法]
每个都建类
[解决办法]
xuexi
[解决办法]
不懂能接点分吗???
[解决办法]
jf
[解决办法]
JF
[解决办法]
学习!我觉得用接口可以实现
[解决办法]
jf
[解决办法]
di
[解决办法]
构造函数重载
通过设置不同参数对构造函数重载

[解决办法]
那你在写够造函数的时候,给UpDate()不带参数,给Delete()带一个int i 的参数可以不,
就是这样
public int UpDate(){}

public int Delete(int i){}


[解决办法]
按需求来说,杨东的解发真的不错,我没想出来。
感觉 saucer 说法很符合.net设计思路。
学习
------解决方案--------------------


路过,帮顶一下
[解决办法]
动态创建类

读书人网 >asp.net

热点推荐