首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Android开发中的密封类实例

Android开发中的密封类实例
EN

Stack Overflow用户
提问于 2019-12-19 09:08:52
回答 2查看 709关注 0票数 0

我是Kotlin的新手。我正在学习sealed classes,我不知道如何在Android开发中使用它。你能给我举个例子吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-12-19 09:27:15

当您想要定义子类的闭包列表时,它非常有用。

您可以使用数据类扩展密封类的可能性。示例:

代码语言:javascript
复制
 fun eval(expr: Expr): Double = when(expr) {
   is Const -> expr.number
   is Sum -> eval(expr.e1) + eval(expr.e2)
   NotANumber -> Double.NaN
  // the `else` clause is not required because we've covered all the cases
 }

声明:

代码语言:javascript
复制
sealed class Expr
data class Const(val number: Double) : Expr()
data class Sum(val e1: Expr, val e2: Expr) : Expr()
object NotANumber : Expr()
票数 3
EN

Stack Overflow用户

发布于 2019-12-19 10:49:43

Kotlin文档说:

密封类用于表示受限的类层次结构,当值可以具有来自有限集合的类型之一,但不能具有任何其他类型时。

让我们举一个简单的例子。您有一个表示布尔表达式的密封抽象类:

代码语言:javascript
复制
sealed class BooleanExpression {
    abstract fun evalate(): Boolean
}

现在,让我们定义一个扩展这个密封类的类:

代码语言:javascript
复制
class OrBooleanExpression(val elem1: Boolean, val elem2: Boolean) : BooleanExpression() {
    override fun evalate() = elem1 or elem2
}

现在,让我们假设我们需要一个只打印布尔表达式成员的方法。对于我们的或布尔表达式,我们将有以下内容:

Elem1真/ Elem2假

我们可以实现如下方法:

代码语言:javascript
复制
fun printMembers(expr: BooleanExpression) = when (expr) {
    is OrBooleanExpression -> print("Elem1 ${expr.elem1} / Elem2 ${expr.elem2}")
}

到目前为止,我们的编译器是快乐的。没什么不对。实际上,在我们的when中,我们已经考虑了密封类的所有子类。

让我们现在添加另一个布尔表达式:

代码语言:javascript
复制
class NotBooleanExpression(val elem1: Boolean) : BooleanExpression() {
    override fun evalate(): Boolean = !elem1
}

现在编译器返回一个错误:

‘当’表达式必须是详尽的,添加必要的‘是NotBooleanExpression’分支或‘其他’分支

现在我们有两种可能来解决这个问题。第一个是为新操作添加一个子句:

代码语言:javascript
复制
fun printMembers(expr: BooleanExpression) = when (expr) {
    is OrBooleanExpression -> print("Elem1 ${expr.elem1} / Elem2 ${expr.elem2}")
    is NotBooleanExpression -> print("Elem1 ${expr.elem1}")
}

或者我们可以添加一个else子句:

代码语言:javascript
复制
fun printMembers(expr: BooleanExpression) = when (expr) {
    is OrBooleanExpression -> print("Elem1 ${expr.elem1} / Elem2 ${expr.elem2}")
    else -> print("Unknown elements")
}

在这两种情况下,编译工作都是因为我们已经处理了密封类的所有子类。

如果现在我们考虑到一个目前没有密封类的语言,比如Java。我们无法在编译时做到这一点。因此,您需要使用设计模式访问者实现以下功能。

代码语言:javascript
复制
interface BooleanExpression {
    abstract Boolean evaluate();

    abstract <T> T accept(Visitor<T> visitor);
}

class NotBooleanExpression implements BooleanExpression {
    private String elem1;    

    public NotBooleanExpression(String elem1) {
        this.elem1 = elem1;
    }

    public Boolean getElem1() {
        return elem1;
    }

    @Override
    public <T> T accept(Visitor<T> visitor) {
        return visitor.visit(this);
    }
}

class OrBooleanExpression implements BooleanExpression {
    private String elem1;
    private String elem2;   

    public NotBooleanExpression(String elem1, String elem2) {
        this.elem1 = elem1;
        this.elem2 = elem2;
    }

    public Boolean getElem1() {
        return elem1;
    }

    public Boolean getElem2() {
        return elem2;
    }

    @Override
    public <T> T accept(Visitor<T> visitor) {
        return visitor.visit(this);
    }
}

class Visitor<T> {
    T visit(NotBooleanExpression expr);

    T visit(OrBooleanExpression expr);
}

class Test {
    public void printMembers(expr: BooleanExpression) {
        expr.accept(new Visitor<Void>() {
            @Override
            public Void visit(NotBooleanExpression expr) {
                System.out.println("Elem1 " + expr.getElem1());

                return null;
            }

            @Override
            public Void visit(OrBooleanExpression expr) {
                System.out.println("Elem1 " + expr.getElem1() + " / Elem2" + expr.getElem2());

                return null;
            }
        };
    }

}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59406395

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档