2015-01-08 3 views
1

Является ли класс по-прежнему считающимся неизменным, если он может быть подклассом (но сохраняются другие правила)? Например:Неизменяемые не заключительные классы

abstract class Figure { 
abstract double area(); 
} 

class Rectangle extends Figure { 
private final double length; 
private final double width; 

Rectangle(double length, double width) { 
    this.length = length; 
    this.width = width; 
} 

double area() { return length * width; } 
} 

Является ли это неизменное?

+0

Что находится на 'Фигуре'? –

+0

Зависит от рисунка – sol4me

+0

абстрактный класс Рисунок { абстрактная двойная область(); } – Dmytro

ответ

2

Поля length и width по-прежнему неизменяемы для всех подклассов (если они не затенены полями подклассов с тем же именем).

Но Подкласс может определять собственные изменчивые поля.

Так ответ: это зависит.

Если вы не наследуете другие классы Rectangle с изменяемыми полями, то да. В противном случае нет.

+0

Так ответ «нет»? – Dmytro

+0

Хуже. Подкласс может скрывать эти неизменные поля! –

+0

см. Обновленный ответ –

0

Если базовый класс сам по себе является неизменным в вашем примере, то да, это неизменно. На языке, таком как Java, который не поддерживает принудительную неизменность компилятора, он подпадает под вас как разработчик для его обработки, и что в основном означает, что любой объект, который не может изменить его состояние, считается неизменным.

В приведенном выше примере вам даже не нужно делать ваши переменные окончательными - факт, что ничто не может их изменить, означает, что он неизменен.

1

Неизменных неконечные классы

не существуют.

Если ваш класс не final, он может быть подклассифицирован.

По определению, неизменяемый класс имеет инварианты. Но если это не final, вы можете подклассифицировать его и ввести поля экземпляров, которые НЕ являются инвариантами. Итак:

public class A 
{ 
    private final int a; 

    public A(final int a) 
    { 
     this.a = a; 
    } 
} 

НЕ неизменна, так как вы можете:

public class B 
    extends A 
{ 
    // NOT AN INVARIANT 
    private int b; 

    public B(final int a) 
    { 
     super(a); 
    } 

    public void setNonInvariant(final int b) 
    { 
     this.b = b; 
    } 
} 

ОДНАКО: класс A является поточно. Но это не является неизменным. И класс B не является потокобезопасным ...

Смежные вопросы