2013-04-08 3 views
0

Я реализую базовую программу расчета заработной платы в Java. У меня есть абстрактный класс супер, который называется Employee, который в основном хранит данные, такие как идентификатор налога, имя и т. Д. Затем у меня есть 2 подкласса Employee под названием Hourly и Salaried, которые должны представлять типы сотрудников. Эти два класса выполняют расчеты оплаты и налога и хранят данные, относящиеся к их типам сотрудников.Java - попытка понять состав

Беда в том, что я получаю кучу полей, так как новые поля должны быть реализованы для хранения рассчитанной заработной платы, налога и т. Д. Я был бы оправдан в избавлении от Salaried и Hourly и создании нового супер класс, PayCalculation, затем имея PayHourly и PaySalaried классы, отменяющие это для реализации часовых/оплачиваемых конкретных полей и расчетов? Если да, то имеет ли смысл иметь соотношение композиций между Employee (суперкласс) и PayCalculation (подкласс)?

У меня нет большого понимания композиции. Если бы кто-нибудь мог подумать о лучшем способе структурирования этого, я бы это очень признал.

Я не знаю, как использовать UML, но вот красивая дрянная диаграмма, которую я сделал в краске, чтобы объяснить это.

enter image description here

+0

Эта ссылка будет полезна для Вас. ** http: //stackoverflow.com/q/2399544/1115584** – AmitG

+0

Спасибо. Мне кажется, что я необоснован в использовании композиции (я не уверен, что это отношения есть). Тем не менее, я не уверен, как структурировать его по-другому. Должен ли я вернуться к предыдущей структуре? –

ответ

1

Employee, Salaried(Employee) и Hourly(Employee) идеально подходят как классы ,

PayCalculation(), PayHourly(), и PaySalaried() звук больше похож на методы, хотя, правильно?

Так что вы можете создать абстрактный метод (это означает, что вы его не реализуете) PayCalculation() в суперклассе (Employee). Затем вы можете (и действительно должны будете) написать реализацию PayCalculation() в своих курсах «Заработная плата» и «Час».

Это означает, что при вызове PayCalculation() на часовом объекте он будет делать совсем по-другому, чем при вызове PayCalculation() на объект Salaried.

Имеет ли это смысл? На самом деле глубоко задумайтесь над этими понятиями - попытка понять концепции наследования действительно пытается понять концепцию объектно-ориентированного программирования в целом.

Пожалуйста, дайте мне знать, если я могу объяснить что-то по-другому - недавно я обволакивал эти понятия.

Кроме того, вы верны в своем комментарии выше. Существует не «имеет» отношения между Employee и Hourly/Salaried. Отношения, которые существуют между ними, это отношения «есть»: почасовый сотрудник IS A.Это означает, что вам нужно думать о inheritance, а не о композиции - это именно то, о чем мы говорили здесь.

Это должен быть отход от этого вопроса: то, что вы пытаетесь понять, - это наследование, а не состав.

+0

Спасибо, это было то, что у меня было раньше. Имеет ли значение, что у меня в классе Employee ~ 10 полей? –

+0

Нет. В. Все. Забавно, я помню, у меня было такое же беспокойство в одной из моих первых программ (что было на самом деле очень похоже на природу этого). Когда я спросил у своего профессора тот же вопрос, он сказал мне, что нет никаких полей, которые повсеместно «слишком много» или «слишком мало». Соответствующее число для любого данного класса, однако, много его потребностей - не больше и не меньше. – drewmoore

+0

ОК, круто! Я предполагаю, что если бы я закончил с bajillions (чего я не буду), я мог бы просто хранить данные в какой-то структуре данных или что-то в этом роде. –

2

Да действительно имеет смысл иметь состав rel'ship между Employee и PayCalculation. Подумайте над этой проблемой практически так: Employee будет иметь payCalculations, workingHourCalculations и т. Д. Как поля/композиции, но не наоборот.

Также Employee могут иметь абстрактные методы для расчета заработной платы, работы и т.д. экземпляр поле Работника может содержать элементы, необходимые для расчета заработной платы, работы и т.д.

Public Employee { 
    private Map payCalMap; 
    ..... 
    public double calculatePay();  
} 
+0

Это тоже выглядит хорошо. Я не уверен, какой из двух ответов я должен реализовать. –

+0

Это всего лишь образец. Вы можете использовать любой тип Datastructure, который соответствует цели. или даже вашей собственной реализации реализаций данных. –

+0

Такие вещи, как расчет оплаты, могут быть размещены в отдельном вспомогательном методе в любом классе полезности. Это связано с тем, что вычисления будут распространены и могут быть повторно использованы. –

2

Расчет оплаты делегатов класса сотрудников методу интерфейса PayCalculation calculate().

Заменяя реализацию этого интерфейса, вы можете достичь другого поведения.

class Employee { 
    private PayCalculation payCalculation; 
    public Employee(PayCalculation calculation){ 
    this.calculation = calculation; 
    } 

    public void calculatePayment(){ 
    payCalculation.calculate(); 
    } 
} 

public interface PayCalculation{ 
    public void calculate(); 
} 

class PayHourly implements PayCalculation{ 
    public void calculation(){ 
    System.out.println("Hourly-paid"); 
    } 
} 

class PaySalaried implements PayCalculation{ 
    public void calculate(){ 
    System.out.println("Salary-paid"); 
    } 
} 

Затем вы создаете 2 различных сотрудников с различными платежными системами:

Employee salaryPaidEmployee = new Employee(new PaySalaried()); 
Employee hourlyPaidEmployee = new Employee(new PayHourly()); 

и расчета оплаты, основанный на системе оплаты:

salaryPaidEmployee.calculatePayment(); 
hourlyPaidEmployee.calculatePayment(); 
+0

Спасибо, это похоже на хороший способ сделать это тоже. –

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