Рассмотрим пример,
class Animal {
public void eat(String str) {
System.out.println("Eating for grass");
}
}
class Goat extends Animal {
public void eat(String str) {
System.out.println("blank");
}
}
class Another extends Goat{
public void eat(String str) {
System.out.println("another");
}
}
public class InheritanceSample {
public static void main(String[] args) {
Animal a = new Animal();
Another t5 = (Another) new Goat();
}
}
В Another t5 = (Another) new Goat()
: вы получите ClassCastException
, потому что вы не можете создать экземпляр класса Another
, используя Goat
.
Примечание. Преобразование действует только в тех случаях, когда класс расширяет родительский класс, а дочерний класс передается его родительскому классу.
Как работать с ClassCastException
:
Эта строка:
n.set(n.get() + 1);
снята в
Number::set(&mut n, n.get() + 1);
Теперь сообщение об ошибке может быть несколько более ясным:
error[E0502]: cannot borrow `n` as immutable because it is also borrowed as mutable
--> <anon>:18:25
|
18 | Number::set(&mut n, n.get() + 1);
| - ^ - mutable borrow ends here
| | |
| | immutable borrow occurs here
| mutable borrow occurs here
Поскольку Rust оценивает аргументы слева направо, этот код эквивалентен этому:
let arg1 = &mut n;
let arg2 = n.get() + 1;
Number::set(arg1, arg2);
Теперь должно быть очевидно, что не так. Перестановка этих первых двух строк исправляет это, но Rust не делает такого анализа управления потоком.
Это было сначала создано как ошибка # 6268 , теперь оно интегрировано в RFC 811 .
Начиная с 1.25.0-ночного 2018-01-13, можно использовать несекснические времена жизни . Если вы запустите свой пример в ночном режиме Rust и включите опцию функции NLL с помощью #![feature(nll)]
, он теперь будет компилироваться без ошибки .