惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

G
Google Developers Blog
人人都是产品经理
人人都是产品经理
腾讯CDC
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
WordPress大学
WordPress大学
S
SegmentFault 最新的问题
小众软件
小众软件
B
Blog
博客园 - 叶小钗
Microsoft Azure Blog
Microsoft Azure Blog
Apple Machine Learning Research
Apple Machine Learning Research
A
About on SuperTechFans
J
Java Code Geeks
Blog — PlanetScale
Blog — PlanetScale
博客园 - 司徒正美
博客园 - 【当耐特】
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Recent Announcements
Recent Announcements
宝玉的分享
宝玉的分享
Martin Fowler
Martin Fowler
Hugging Face - Blog
Hugging Face - Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Last Week in AI
Last Week in AI
V
V2EX

博客园 - 方东信

【far 语言】语言文档目录 【far 语言】注解系统 【far 语言】数组 【far 语言】并发编程(协程) 【far 语言】控制流 【far 语言】异常处理 【far 语言】farcc 构建工具 【far 语言】函数 【far 语言】接口与泛型 【far 语言】List 列表 【far 语言】Map 映射 【far 语言】原生内存与 FFI 【far 语言】字符串 【far 语言】语法总览 【far 语言】类型系统 Java 远程调用类,控制类的办法,老了,记不住了。靠 java opc ua 基于s7 音视频:JavaCV 采集桌面画面并显示的方法 pand3d实现服务端渲染并推流 UI弹窗遮罩屏蔽触发事件的处理 far的数据类型 Windows下Tesseract-OCR的安装与使用 LoRA配置 大模型三阶段训练方法(LLaMa Factory) windows系统下anaconda的安装和使用 trl ppo 【手把手从零实现】Qwen2.5-VL:环境配置/功能实验(图片识别理解、目标检测、文字OCR、文档解析、视频理解)/模型微调(MS-Swift 和 LLaMA-Factory) seata 1.8.0 报错大全 Springboot 报错 java.lang.IllegalStateException: block()/blockFirst()/blockLast() are blocking vLLM部署多模态大模型Qwen2.5-VL-3B-Instruct
【far 语言】组合与继承
方东信 · 2026-09-13 · via 博客园 - 方东信

本文是「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,运行期校验失败会抛异常。
  • 父类类型的形参、字段、数组/容器元素同样支持多态。

覆盖与 super

class 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
  • 子类定义同签名方法与父类 ⇒ 覆盖(override),多态分派走子类实现。
  • 同名但签名不同 ⇒ 视为重载,不是覆盖。
  • 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 Agedinterface Aged : NamedDog 天然满足 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 Nameda 的实现类 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);      // 第二组
  • 重载与变长参数见 function.md
  • 子类重载不会改变父类已有方法的符号,二者互不影响。

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
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。