













本文是「far 语言」系列文档之一,总目录见《【far 语言】语言文档目录》。
Far 支持单继承 + 完整多态。多能力通过 impl 接口列表表达。
class 子类 : 父类 impl 接口1, 接口2 {
// 子类成员
}
| 形态 | 示例 |
|---|---|
| 仅继承 | class Cat : Animal { } |
| 仅接口 | class Box impl IShow { } |
| 继承 + 多接口 | class Dog : Animal impl INamed, IRunner { } |
| 泛型 + 继承 + 接口 | class Box<T> : Base<T> impl IShow { } |
class A : B, C { } 会报错——多能力请用接口。extends 关键字未启用,写了会得到指向 : 的友好报错。impl → 接口列表」。class Animal {
long hp = 100; // 字段初始化器
string kind = "animal";
string speak(){ return "animal"; }
long getHp(){ return this.hp; }
}
class Dog : Animal {
long bark(){ return 7; }
}
Dog d = new Dog();
println(d.hp); // 100 —— 父类字段初始化器自动执行
println(d.getHp()); // 100 —— 继承父类方法
println(d.bark()); // 7 —— 子类自有方法
getA() 定义在祖父类上也能调用。父类类型的变量可以持有子类实例,方法调用按运行期实际类型分派:
class Animal {
string speak(){ return "animal"; }
}
class Dog : Animal {
string speak(){ return "woof"; }
}
class Cat : Animal {
string speak(){ return "meow"; }
}
Animal a = new Dog();
println(a.speak()); // woof —— 分派到 Dog 实现
a = new Cat();
println(a.speak()); // meow —— 同一变量换绑,分派随之变化
Animal xs[3] = [new Dog(), new Cat(), new Animal()];
println(xs[0].speak()); // woof
as,运行期校验失败会抛异常。superclass Animal {
long legs(){ return 4; }
string speak(){ return "animal"; }
}
class Dog : Animal {
@Override
string speak(){ return super.speak() + "+woof"; }
long total(){ return super.legs() + 1; }
}
println(new Dog().speak()); // animal+woof
println(new Dog().total()); // 5
super.method() 静态调用父类实现(不参与多态分派),编译期直接绑定父类符号。@Override 是可选断言:写了就要求父链或所实现接口中确实存在同签名方法,否则编译报错——
用来拦「以为覆盖了、其实签名写错」的静默 bug。它也可用于声明「实现了接口方法」。interface Named {
string name();
}
class Animal impl Named {
string name(){ return "animal"; }
}
class Dog : Animal { // 未写 impl
string name(){ return "dog"; }
}
Named n = new Dog(); // OK:父类 impl 的接口,子类天然满足
println(n.name()); // dog —— 分派到子类实现
impl 的接口,子类天然满足(Java IS-A 语义),无需重复声明。class Dog impl Aged 且 interface Aged : Named ⇒
Dog 天然满足 Named,可直接赋给 Named 变量;接口 → 父接口的赋值也成立。
细节见 interface-generic.md 的「接口继承与满足性」。new X()),调用走动态分派。向上转型(子类 → 父类)自动成立;向下转型必须显式 as,运行期校验:
class Animal { }
class Dog : Animal { long bark(){ return 7; } }
class Cat : Animal { }
Animal a = new Dog();
Dog d = a as Dog; // 校验通过 → 得到 Dog 视图
println(d.bark()); // 7
Cat c = a as Cat; // 校验失败 → 抛异常(Cannot cast Dog to Cat)
as 校验的是运行期实际类;失败抛异常(catch (Exception e) 可捕获),不会返回 null。a as Named 在 a 的实现类 impl 了 Named 时通过。as 直接把父类类型赋给子类变量是编译错误(禁止隐式向下转型)。object 源同样受此约束(对齐 Java:Object o; Named n = o; 是编译错误):必须显式 as,
且变量声明 / 实参 / return / 数组元素四条路径口径一致:
Named n = o as Named; · take(o as Named); · return c as HttpConn;。
该约束只针对以「用户声明的类 / 接口」为目标的情形;T → object(向上)恒可,
其余目标(object 自身、string / long / map 等内建类型)维持既有宽松。| 写法 | 报错 |
|---|---|
class C : A, B { } |
只支持单继承,多能力请用 impl |
class Dog extends Animal { } |
extends 未启用,继承统一用冒号 |
循环继承 A : B + B : A |
继承链形成环 |
| 子类字段与父类同名 | 禁止字段遮蔽 |
@Override 标在无同签名可覆盖的方法上 |
断言失败 |
| 继承不存在的父类 | 父类未定义 |
class Fmt : Base {
string fmt(long... nums){ /* nums 是 long[] */ }
string fmt(string s, long... rest){ /* ... */ }
}
Fmt f = new Fmt();
f.fmt(1, 2, 3); // 第一组
f.fmt("a", 1, 2); // 第二组
Rust编程语言群 1036955113
java新手自学群 626070845
java/springboot/hadoop/JVM 群 4915800
Hadoop/mongodb(搭建/开发/运维)Q群481975850
GOLang Q1群:6848027
GOLang Q2群:450509103
GOLang Q3群:436173132
GOLang Q4群:141984758
GOLang Q5群:215535604
C/C++/QT群 1414577
单片机嵌入式/电子电路入门群群 306312845
MUD/LIB/交流群 391486684
Electron/koa/Nodejs/express 214737701
大前端群vue/js/ts 165150391
操作系统研发群:15375777
汇编/辅助/破解新手群:755783453
大数据 elasticsearch 群 481975850
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。