我的问题几乎就是标题所说的:是否有可能拥有一种不允许显式类型转换的编程语言?
为了澄清我的意思,假设我们正在使用一些类似 C# 的语言,有一个父Base
类和一个子Derived
类。显然,这样的代码是安全的:
Base a = new Derived();
由于向上继承层次结构是安全的,但是
Dervied b = (Base)a;
不能保证安全,因为下去是不安全的。
但是,不管安全性如何,这种向下转换在许多语言(如 Java 或 C#)中都是有效的 - 代码将编译,如果类型不正确,它将在运行时失败。所以从技术上讲,代码仍然是安全的,但是通过运行时检查而不是编译时检查(顺便说一句,我不喜欢运行时检查)。
我个人会发现完整的编译时类型安全非常重要,至少从理论角度来看,最多从可靠代码的角度来看。编译时类型安全的一个结果是不再需要强制转换(我认为这很好,因为无论如何它们都很丑)。任何类似强制转换的行为都可以通过隐式转换运算符或构造函数来实现。
所以我想知道,目前是否有任何 OO 语言在编译时提供如此严格的类型安全,以至于强制转换已过时?即,他们不允许任何不安全的转换操作?或者有什么原因这不起作用?
感谢您的任何意见。
编辑
如果我可以举例说明,这就是我如此讨厌沮丧的主要原因。
假设我有以下内容(大致基于 C# 的集合):
public interface IEnumerable<T>
{
IEnumerator<T> GetEnumerator();
IEnumerable<T> Filter( Func<T, bool> );
}
public class List<T> : IEnumerable<T>
{
// All of list's implementation here
}
现在假设有人决定编写如下代码:
List<int> list = new List<int>( new int[]{1, 2, 3, 4, 5, 6} );
// Let's filter out the odd numbers
List<int> result = (List<int>)list.Filter( x => x % 2 != 0 );
请注意最后一行的演员表是如何必要的。但它有效吗?一般不会。List<T>.Filter
当然,实现将返回另一个是有道理的List<T>
,但这不是保证(它可以是 的任何子类型IEnumerable<T>
)。即使它在某个时间点运行,以后的版本也可能会改变这一点,暴露出代码的脆弱性。
几乎所有我认为需要向下转换的情况都可以归结为像这个例子这样的东西——一个方法具有某个类或接口的返回类型,但是由于我们知道一些实现细节,我们有信心向下转换结果。但这是反 OOP 的,因为 OOP 实际上鼓励从实现细节中抽象出来。那么我们为什么要这样做,即使是纯粹的 OOP 语言呢?