Иерархия наследования и преобразование типов
В прошлой главе говорилось о преобразованиях объектов простых типов. Однако с
объектами классов все происходит немного по-другому. Допустим, у нас есть следующая
иерархия классов:
// абстрактный класс человека
public abstract class Person {
private String name;
public String getName() { return name; }
public Person(String name){
this.name=name;
}
public abstract void displayInfo();
}
// класс служащего компании
class Employee extends Person{
private String company;
public Employee(String name, String company) {
super(name);
this.company=company;
}
public String getCompany(){
return this.company;
}
public void displayInfo(){
System.out.println("Имя: " + super.getName() + " Работает в : " +
company);
}
}
// класс клиента банка
class Client extends Person{
private int sum; // Переменная для хранения суммы
private int percentage; // Переменная для хранения процента
private String bank;
public Client(String name, String bank, int sum, int percentage) {
super(name);
this.bank=bank;
this.sum=sum;
this.percentage=percentage;
}
public void displayInfo(){
System.out.println("Имя: " + super.getName() + " Имеет счет в банке: " +
bank);
}
public String getBank(){
return this.bank;
}
public int getSum(){
return this.sum;
}
public int getPercentage(){
return this.percentage;
}
}
В этой иерархии классов можно проследить следующую цепь наследования: Object (все
классы неявно наследуются от типа Object) -> Person -> Employee|Client.
Используем классы в программе и проведем несколько преобразований:
Object emp = new Employee("Bill", "Microsoft");
Person cl = new Client("Tom", "UnitBank", 200, 20);
//у класса Object нет метода displayInfo, поэтому приводим к классу Employee
((Employee)emp).displayInfo();
// у класса Person есть метод displayInfo
cl.displayInfo();
// у класса Person нет метода getBank(), поэтому приводим к классу Client
String bank = ((Client)cl).getBank();
Здесь вначале создаются две переменные типов Оbject и Person, которые хранят ссылки на
объекты Employee и Client соответственно. В данном случае работает неявное преобразование,
так как наши переменные представляют классы Object и Person, поэтому допустимо неявное
восходящее преобразование - преобразование к типам, которые находятся вверху иерархии
классов:
Object
|
Person--Client
|
Employee
Однако при применении этих переменных нам придется использовать явное
преобразование. Поскольку переменная emp хранит ссылку на объект типа Employee, то мы
можем преобразовать к этому типу: ((Employee)emp).Display(). То же самое и с переменной cl.
В то же время мы не можем привести переменную emp к объекту Client, например, так:
((Client)emp).Display();, так как класс Client не находится в иерархии классов между Employee и
Object.
Добавим еще класс Manager, который будет наследоваться от класса Employee и поэтому
будет находиться в самом низу иерархии классов:
class Manager extends Employee{
public Manager(String name, String comp) {
super(name,comp);
}
public void displayInfo(){
System.out.println("Имя: " + super.getName() + " Менеджер банка " +
super.getCompany());
}
}
И поскольку объект класса Manager в то же время является и сотрудником банка (то есть
объектом Employee), мы можем использовать этот класс следующим образом:
Employee man = new Manager("John", "City Bank");
man.displayInfo(); // преобразование не нужно, так как в классе Employee есть
метод displayInfo
Тут опять же восходящее преобразование Manager к Employee. И так как метод displayInfo
есть у класса Employee, нам не надо выполнять преобразование переменной к типу Manager.
Но
рассмотрим
противоположную
ситуацию:
если
мы
применим
нисходящие
преобразования неявно, то мы получим во время выполнения программы ошибку:
Manager man = new Employee("John", "City Bank");
man.displayInfo();
В данном случае мы пытаемся неявно преобразовать объект Emloyee к типу Manager. Но
если Manager является объектом типа Emloyee, то объект Emloyee не является объектом типа
Manager. И перед тем, как провести преобразование типов, мы можем проверить, а можем ли мы
выполнить приведение с помощью оператора instanceof:
Employee emp = new Employee("John", "City Bank");
if(emp instanceof Manager){
((Manager)emp).displayInfo();
}
else{
System.out.println("Преобразование не допустимо");
}
Выражение emp instanceof Manager проверяет, является ли переменная emp объектом типа
Manager. Но так как в данном случае явно не является, то такая проверка вернет значение false, и
преобразование не сработает.
Do'stlaringiz bilan baham: |