Использование свойств потомка через родителя java
Есть 2 класса:
public class Parent {
String parentString;
public Parent() {}
public Parent(String parentString) {
this.parentString = parentString;
}
}
public class Child extends Parent{
private String childString;
public Child() {}
public Child(String childString) {
this.childString = childString;
}
public String getChildString() {
return childString;
}
}
И вот такой код:
public static void main(String[] args) {
Child c = new Child("child");
method(c);
}
public static void method(Parent p) {
Child c = (Child) p;
System.out.println(c.getChildString());
}
Вопрос: насколько такой код корректен? Мы как параметр отправляем ссылку на объект в памяти, всегда ли я смогу скастить родителя к наследнику, если отправляю наследника? Понимаю, что если отправить родителя, то будет Exception, это я отловлю.
Ред: метод универсален, исправить сигнатуру не могу(это библиотека, используемая не только моим проектом), но могу дописать код в сам метод, который не будет ломать функциональность.
Ред2: Классы родителя и потомка редактировать крайне проблемно и не всегда возможно. Родителя, скорее всего, править вообще не дадут.
Ответы (2 шт):
Технически так можно, но некрасиво. Некрасиво в том смысле, что не ложится в общую концепцию ООП и Java в частности. По идее надо делать примерно так:
public class Parent {
String parentString;
public Parent() {}
public Parent(String parentString) {
this.parentString = parentString;
}
public String getChildString() {return null;} //можно просто объявить abstract
}
public class Child extends Parent{
private String childString;
public Child() {}
public Child(String childString) {
this.childString = childString;
}
@Overrides
public String getChildString() {
return childString;
}
}
Если позволяют обстоятельства то Parent можно объявить абстрактным.
В таком случае, никаких дурацких кастов не возникает:
public static void method(Parent p) {
System.out.println(p.getChildString());
}
Можно передать Child в Parent и тогда делать верхний кастинг, но вы не можете гарантировать, что такое приведение типов будет работать. Инспекция IntelliJ уже выдала бы предупреждение, что возможно неверный кастинг. Исправить можно, но это как я уже говорил некорректный способ, в случае если код написан некорректно, то приходится его использовать.
public static void method(Parent p) {
if (p instanceof Child) {
Child c = (Child) p;
System.out.println(c.getChildString());
}
}