Oop 使用面向对象方法实现类型安全
我试图思考如何使用面向对象的方法正确地解决这个问题。语言并不重要——实际上我想写代码,但更重要的是我关心的一般原则 我想实现一个:一个“数字”集合,操作+、-、*、和/操作在该集合上进行。此外,我希望能够实现更高的操作,如^和循环查找(cycle finding),这些操作(1)不需要为给定字段定义,但(2)可以在需要时重写,比如出于效率原因 这是陷阱。不够好,不能申报Oop 使用面向对象方法实现类型安全,oop,language-agnostic,computer-science,liskov-substitution-principle,Oop,Language Agnostic,Computer Science,Liskov Substitution Principle,我试图思考如何使用面向对象的方法正确地解决这个问题。语言并不重要——实际上我想写代码,但更重要的是我关心的一般原则 我想实现一个:一个“数字”集合,操作+、-、*、和/操作在该集合上进行。此外,我希望能够实现更高的操作,如^和循环查找(cycle finding),这些操作(1)不需要为给定字段定义,但(2)可以在需要时重写,比如出于效率原因 这是陷阱。不够好,不能申报 FieldElement power (FieldElement base, FieldElement exponent)
FieldElement power (FieldElement base, FieldElement exponent)
因为我想要类型安全性:比如说,不可能将有限域的一个成员添加到整数中
也许我真正想要的是一个元对象,或者超级接口,或者把不同的类联系在一起的东西(一个用于整数,一个用于7-adic,一个用于有限域F_4,等等)。或者有更好的办法
如果答案是有启发性的,那么N.B.代码在回答中是受欢迎的(甚至是受鼓励的),但声明可能就足够了:这里的每个人大概都可以为至少几个字段写出明显的方法
我将提到其他对我很重要但(显然)与主要OO问题无关的条件:我不希望字段元素携带其类型信息,而且我希望它们是轻量级的(因为我可能需要处理大量字段元素数组)。这些要求可能无法实现,但坦白地说,我更可能放弃OO而不是效率。但是不管怎样,我都希望得到一个答案,因为我有兴趣了解这些问题,甚至除了手头的特定问题。这就是所谓的二进制方法问题。快速谷歌搜索将显示一些(大量)信息。特别是卢卡·卡德利等人的“关于二进制方法”一文对这一主题进行了彻底的论述 您可能想学习一些Haskell,看看实用编程语言如何处理这个问题
编辑洛卢卡→ 卢卡。该死的小手机屏幕和更小的键盘;) 我以前曾试图用C语言表达这些概念,但我遇到了语言障碍:语言不够丰富,或者不够具体。例如,如果我这样定义字段的元素:
public abstract class FieldElement
{
public abstract FieldElement Add(FieldElement another);
public abstract FieldElement SumInvert();
public abstract FieldElement MultiplicationInvert();
public abstract FieldElement MultiplyBy(FieldElement another);
public abstract FieldElement One; //Multiplication neutral element
public abstract FieldElement Zero; //Addition neutral element
public FieldElement Subtract(FieldElement another)
{
return this.Add(another.SumInvert());
}
public FieldElement Divide(FieldElement another)
{
return this.MultiplyBy(another.MultiplicationInvert());
}
public virtual FieldElement Power(uint b)
{
if (b == 0)
return this.One;
else
{
FieldElement result = this;
for (int i = 0; i < b - 1; i++)
result = result.MultiplyBy(result);
return result;
}
}
}
public class RealNumber : FieldElement
{
public double Value { get; set; }
public RealNumber(double value)
{
this.Value = value;
}
public override FieldElement Power(uint b)
{
return new RealNumber(Math.Pow(Value, b));
}
public override FieldElement Add(FieldElement another)
{
if (another.GetType() != typeof(RealNumber)) //Ugly typecast to enforce type-safety
throw new ArgumentException("RealNumber expected in Add method");
return new RealNumber(Value + (another as RealNumber).Value);
}
}
然后,我可以(通过使用泛型)在字段元素上定义泛型操作:
公共类FieldOperations,其中T:FieldElement
{
公共T添加(T a,T b)
{
返回a.Add(b)作为T;
}
公共T乘(T a,T b)
{
将a乘以(b)作为T返回;
}
公共T减法(T a,T b)
{
返回a.减去(b)作为T;
}
公共T分割(T a,T b)
{
返回a。将(b)除以T;
}
公共电力(TA、uint b)
{
将a.Power(b)返回为T;
}
}
我将在代码中这样使用它:
public class TestFieldOperations
{
public static void TestAddRealNumbers()
{
FieldOperations<RealNumber> operations = new FieldOperations<RealNumber>();
RealNumber a = new RealNumber(0.5);
RealNumber b = new RealNumber(0.7);
RealNumber c = operations.Add(a, b);
RealNumber d = operations.Power(c, 3);
}
}
公共类TestFieldOperations
{
公共静态无效TestAddressRealNumbers()
{
FieldOperations=新的FieldOperations();
实数a=新实数(0.5);
RealNumber b=新的RealNumber(0.7);
RealNumber c=操作。添加(a,b);
realnumed d=操作功率(c,3);
}
}
类似地,我可以对向量进行FieldOperations,对InvMatrix进行FieldOperations
能够以类型安全和面向对象的方式抽象字段操作的概念可能非常强大:能够在相同的抽象级别上处理数字、向量和(可逆)矩阵算法 “语言不重要”——我敢肯定它是重要的。例如,C++的解决方案可能是java中不存在的模板(它们是这样的,以泛型的形式存在)。例如,你可以说这需要有界参数多态性,鉴于此,你在语言X中能做的最好的事情就是使用功能Y。语言功能不是孤立存在的——人们从事计算机科学工作会得到报酬。。。但我想你可能会争辩说,你最好在不同的网站上问这个问题(compsci是什么?),你可以试试这是一个我觉得可以在几个不同地方问的问题的例子。我肯定它会在cstheory.se关闭,但也许cs.se会接受它。我不知道两者都存在。理论是研究吗?不管怎样,就我个人而言,我很高兴你在这里问我。对空指针、访问和正则表达式进行更改。这是如何处理重写操作的?假设定义了一个求幂运算符
public T Power(ta,unsigned int b)
,如果b为0,则返回T.one
,否则返回a.Multiply(Power(a,b-1))
。当我有一个FieldOperations
时,我想让它运行。但是我想要一个不同的函数来覆盖RealNumber
s,这将更加有效。这可能吗?上面编辑的原始答案。这不是你想要的。这只是一个解决办法。函数幂是抽象定义的,然后重新定义为实数。
public class TestFieldOperations
{
public static void TestAddRealNumbers()
{
FieldOperations<RealNumber> operations = new FieldOperations<RealNumber>();
RealNumber a = new RealNumber(0.5);
RealNumber b = new RealNumber(0.7);
RealNumber c = operations.Add(a, b);
RealNumber d = operations.Power(c, 3);
}
}