谷歌面试题:继承关系变组合关系

题目描述

一个项目中有Employee类型,该类型是个大类型,下分为Engineer类型和Manager类型。比方一个人开始是Engineer类型,后来升职了,变成了Manager的角色,这种情况,应该如何建模更好一些。

思路

变继承关系为组成关系,方便扩展。

代码

定义一个Role的接口:

public interface Role {
    void doWork();
}

定义Employee类型:

public class Employee {
    private final String name;
    private final int salary;
    private Role role;

    public Employee(String name, int salary, Role role) {
        this.name = name;
        this.salary = salary;
        this.role = role;
    }

    public String getName() {
        return name;
    }

    public int getSalary() {
        return salary;
    }

    public Role getRole() {
        return role;
    }

    public void setRole(Role role) {
        this.role = role;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "name=‘" + name + ‘\‘‘ +
                ", salary=" + salary +
                ", role=" + role +
                ‘}‘;
    }

    public void doWork(){
        this.role.doWork();
    }
}

定义Engineer类型:

public class Engineer implements Role {
    @Override
    public void doWork() {
        System.out.println("Doing Engineer work.");
    }

    @Override
    public String toString() {
        return "Engineer";
    }
}

定义Manager类型:

import java.util.ArrayList;
import java.util.List;

public class Manager implements Role {
    private List<Employee> reporters;

    public Manager(List<Employee> reporters) {
        this.reporters = new ArrayList<>(reporters);
    }

    @Override
    public void doWork() {
        System.out.println("Dispatching work.");
        Employee employee = selectReporter();
        employee.doWork();
    }

    private Employee selectReporter() {
        return reporters.get(0);
    }

    @Override
    public String toString() {
        return "Manager";
    }
}

最后进行测试,将“陈驰”的角色由Engineer变成Manager :

import java.util.Arrays;

public class Test {
    public static void main(String[] args) {
        Employee employee1 = new Employee("陈驰", 20000, new Engineer());
        Employee employee2 = new Employee("魏印福", 20000, new Engineer());

        System.out.println(employee1);
        System.out.println(employee2);

        System.out.println("Employee1:");
        employee1.doWork();
        System.out.println("Employee2:");
        employee2.doWork();

        System.out.println("职位升迁......");

        employee1.setRole(new Manager(Arrays.asList(employee2)));
        System.out.println(employee1);
        System.out.println(employee2);

        System.out.println("Employee1:");
        employee1.doWork();
        System.out.println("Employee2:");
        employee2.doWork();
    }
}

查看测试结果:

原文地址:https://www.cnblogs.com/DarrenChan/p/10344040.html

时间: 2024-10-03 00:06:56

谷歌面试题:继承关系变组合关系的相关文章

黑马程序员-OC面向对象继承关系和组合关系笔记

继承关系是描述类和类之间的关系,两个类分别称为子类和父类,子类继承了父类,子类就拥有了父类的属性和方法: 继承的关系特点描述出来就是:** "是" **  (例如:学生类 是 人类) 组合关系描述的语句是:**** "拥有" ***  (例如:学生有成绩这个属性,而成绩属性本来就是一个成绩类的对象 ) 继承示例代码: #import <Foundation/Foundation.h> //Animal类的声明 @interface Animal : NS

7,装饰者模式(Decorator Pattern)动态的给一个对象添加一些额外的职责。就增加功能来说,此模式比生成子类更为灵活。继承关系的一个替换方案。

装饰( Decorator )模式又叫做包装模式.通过一种对客户端透明的方式来扩展对象的功能,是继承关系的一个替换方案. 装饰模式就是把要添加的附加功能分别放在单独的类中,并让这个类包含它要装饰的对象,当需要执行时,客户端就可以有选择地.按顺序地使用装饰功能包装对象. 在装饰模式中的各个角色有: 抽象构件(Component)角色:给出一个抽象接口,以规范准备接收附加责任的对象. 具体构件(Concrete Component)角色:定义一个将要接收附加责任的类. 装饰(Decorator)角色

对象关系分析(非继承关系)

现实环境存在各种对象关系,可以使用特殊的关系类型描述词来形容这些关系. 例如: 1. 方形是属于形状的一种,可以用"is-a"来描述方形与形状的关系. 2. 汽车都有方向盘,可以用"has-a"来描述汽车与方向盘的关系. 3. 程序员使用键盘编辑代码,可以用"uses-a"来描述程序员与键盘的关系. 4. 花朵依赖蜜蜂传播花粉,可以使用"depends-on"来描述花朵与蜜蜂的关系. 5. 学生是一个班级的成员,可以使用&qu

【重构学习】10 继承关系的重构

1.字段上移 修改点:两个子类拥有相同的字段 做法:将该字段移至父类 2.函数上移 修改点:有些函数,在各个子类中产生完全相同的效果 做法:将该函数移至父类 有一种特殊情况也需要这么做:子类函数覆盖了父类的,但是仍然做着相同的工作 在此重构中你可能会遇到一种情况,就是你提炼的函数调用了子类有而父类没有的函数,那么在父类中给此父类没有的函数,建立一个虚函数即可. 3.构造函数本体上移 修改点:你在各个子类中拥有一些构造函数,它们的本体几乎完全一致 做法:在父类中新建一个构造函数,并在子类构造函数中

Effective c++(笔记)之继承关系与面向对象设计

1.公有继承(public inheritance) 意味着"是一种"(isa)的关系 解析:一定要深刻理解这句话的含义,不要认为这大家都知道,本来我也这样认为,当我看完这章后,就不这样认为了. 公有继承可以这样理解,如果令class D以public 的形式继承了class B ,那么可以这样认为,每一个类型为D的对象同时也可以认为是类型为B的对象,但反过来是不成立的,对象D是更特殊化更具体的的概念,而B是更一般化的概念,每一件事情只要能够施行于基类对象身上,就一定可以应用于派生类对

js继承关系

跟传统面向对象语言比起来,js在继承关系方面比较特别,如果第一次看恐怕会有些抓狂,偶就是这样(又透露小白本质#=_=),从哪里说起好呢?函数调用? js中函数的调用方式大致可分以下几种: 1. 普通函数,直接调用 function Hi(){ alert(233); } Hi(); var f = function(){ alert(666); }; f(); 2. 作为对象的方法调用 var obj = { x:1, m:function(){ alert("hello"); } }

Servlet生命周期 和 继承关系

三 servlet的生命周期 (一个servlet类的对象 创建---->销毁) 第一次访问 某个servlet的时候 首先调用其 构造函数 public StudentServlet(){ System.out.println("servlet被创建了"); } 第一次访问 在构造函数之后 调用其 init初始化方法 : 功能 配置一些初始化参数 @Override public void init() throws ServletException { System.out.

类之间的依赖关系和组合关系

目录 类之间的依赖关系和组合关系 依赖(关联)关系 组合(聚合)关系 一对多的组合关系 类之间的依赖关系和组合关系 依赖(关联)关系 类之间可以有三种关系: 依赖(关联)关系 组合(聚合)关系 继承(实现)关系 依赖(关联)关系指的是类对象执行某个动作的时候,需要其他类的对象来帮助完成这个操作的情况,其特点为: 将一个类的对象或者类名传到另一个类的方法中使用 此时的关系是最轻的,随时可以更换其他对象 关联关系的示例如下: class Person: def play(self, tools):

QObject提供了QMetaObject元类信息(相当于RTTI和反射),信号与连接,父子关系,调试信息,属性,事件,继承关系,窗口类型,线程属性,时间器,对象名称,国际化

元类信息(相当于RTTI和反射),信号与连接,父子关系,调试信息,属性,事件,继承关系,窗口类型,线程属性,时间器,对象名称,国际化其中元类又提供了:classInfo,className,构造函数,多重祖先元类,method, property, Enumerator, Signal, Slot等等 http://doc.qt.io/qt-5/qobject.html http://doc.qt.io/qt-5/qmetaobject.html 我感觉Qt的出现,除了提供GUI以外,主要就是提