Лекция
Привет, сегодня поговорим про отношения классов в uml, обещаю рассказать все что знаю. Для того чтобы лучше понимать что такое отношения классов в uml , настоятельно рекомендую прочитать все из категории Объектно-ориентированное программирование ООП.
Класс
Класс (class) в языке UML служит для обозначения множества объектов, которые обладают одинаковой структурой, поведением и отношениями с объектами из других классов. Графически класс изображается в виде прямоугольника, который дополнительно может быть разделен горизонтальными линиями на разделы или секции (рис. 5.1). В этих разделах могут указываться имя класса, атрибуты (переменные) и операции (методы).
Рис. 5.1. Графическое изображение класса на диаграмме классов
Обязательным элементов обозначения класса является его имя. На начальных этапах разработки диаграммы отдельные классы могут обозначаться простым прямоугольником с указанием только имени соответствующего класса (рис. 5.1, а). По мере проработки отдельных компонентов диаграммы описания классов дополняются атрибутами (рис. 5.1, б) и операциями (рис. 5.1, в).
Предполагается, что окончательный вариант диаграммы содержит наиболее полное описание классов, которые состоят из трех разделов или секций. Иногда в обозначениях классов используется дополнительный четвертый раздел, в котором приводится семантическая информация справочного характера или явно указываются исключительные ситуации.
Даже если секция атрибутов и операций является пустой, в обозначении класса она выделяется горизонтальной линией, чтобы сразу отличить класс от других элементов языка UML. Примеры графического изображения классов на диаграмме классов приведены на рис. 5.2. В первом случае для класса "Прямоугольник" (рис. 5.2, а) указаны только его атрибуты - точки на координатной плоскости, которые определяют его расположение. Для класса "Окно" (рис. 5.2, б) указаны только его операции, секция атрибутов оставлена пустой. Для класса "Счет" (рис. 5.2, в) дополнительно изображена четвертая секция, в которой указано исключение - отказ от обработки просроченной кредитной карточки.
Рис.5.2. Примеры графического изображения классов на диаграмме
Имя класса
Имя класса должно быть уникальным в пределах пакета, который описывается некоторой совокупностью диаграмм классов (возможно, одной диаграммой). Оно указывается в первой верхней секции прямоугольника. В дополнение к общему правилу наименования элементов языка UML, имя класса записывается по центру секции имени полужирным шрифтом и должно начинаться с заглавной буквы. Рекомендуется в качестве имен классов использовать существительные, записанные по практическим соображениям без пробелов. Необходимо помнить, что именно имена классов образуют словарь предметной области при ООАП.
В первой секции обозначения класса могут находиться ссылки на стандартные шаблоны или абстрактные классы, от которых образован данный класс и, соответственно, от которых он наследует свойства и методы. В этой секции может приводиться информация о разработчике данного класса и статус состояния разработки, а также могут записываться и другие общие свойства этого класса, имеющие отношение к другим классам диаграммы или стандартным элементам языка UML.
Примерами имен классов могут быть такие существительные, как "Сотрудник", "Компания", "Руководитель", "Клиент", "Продавец", "Менеджер", "Офис" и многие другие, имеющие непосредственное отношение к моделируемой предметной области и функциональному назначению проектируемой системы.
Класс может не иметь экземпляров или объектов. В этом случае он называется абстрактным классом, а для обозначения его имени используется наклонный шрифт (курсив). В языке UML принято общее соглашение о том, что любой текст, относящийся к абстрактному элементу, записывается курсивом. Данное обстоятельство является семантическим аспектом описания соответствующих элементов языка UML.
public class Man{
protected String name;
protected String surname;
public void setName(String newName){
name = newName;
}
public String getName(){
return name;
}
public void setSurname(String newSurname){
name = newSurname;
}
public String getSurname(){
return surname;
}
}
// наследуем класс Man
public class Employee extends Man{
private String position;
// создаем и конструктор
public Employee(String n, String s, String p){
name = n;
surname = s;
position = p;
}
public void setPosition(String newProfession){
position = newProfession;
}
public String getPosition(){
return position;
}
}
public class Employee extends Man{
private String position;
private IdCard iCard;
public Employee(String n, String s, String p){
name = n;
surname = s;
position = p;
}
public void setPosition(String newPosition){
position = newPosition;
}
public String getPosition(){
return position;
}
public void setIdCard(IdCard c){
iCard = c;
}
public IdCard getIdCard(){
return iCard;
}
}
public class IdCard{
private Date dateExpire;
private int number;
public IdCard(int n){
number = n;
}
public void setNumber(int newNumber){
number = newNumber;
}
public int getNumber(){
return number;
}
public void setDateExpire(Date newDateExpire){
dateExpire = newDateExpire;
}
public Date getDateExpire(){
return dateExpire;
}
}
IdCard card = new IdCard(123);
card.setDateExpire(new SimpleDateFormat("yyyy-MM-dd").parse("2015-12-31"));
sysEngineer.setIdCard(card);
System.out.println(sysEngineer.getName() +" работает в должности "+ sysEngineer.getPosition());
System.out.println("Удостовирение действует до " + new SimpleDateFormat("yyyy-MM-dd").format(sysEngineer.getIdCard().getDateExpire()) );
public class Room{
private int number;
public Room(int n){
number = n;
}
public void setNumber(int newNumber){
number = newNumber;
}
public int getNumber(){
return number;
}
}
...
private Set room = new HashSet();
...
public void setRoom(Room newRoom){
room.add(newRoom);
}
public Set getRoom(){
return room;
}
public void deleteRoom(Room r){
room.remove(r);
}
...
public static void main(String[] args){
Employee sysEngineer = new Employee("John", "Connor", "Manager");
IdCard card = new IdCard(123);
card.setDateExpire(new SimpleDateFormat("yyyy-MM-dd").parse("2015-12-31"));
sysEngineer.setIdCard(card);
Room room101 = new Room(101);
Room room321 = new Room(321);
sysEngineer.setRoom(room101);
sysEngineer.setRoom(room321);
System.out.println(sysEngineer.getName() +" работает в должности "+ sysEngineer.getPosition());
System.out.println("Удостовирение действует до " + sysEngineer.getIdCard().getDateExpire());
System.out.println("Может находиться в помещеньях:");
Iterator iter = sysEngineer.getRoom().iterator();
while(iter.hasNext()){
System.out.println( ((Room) iter.next()).getNumber());
}
}
public class Department{
private String name;
private Set employees = new HashSet();
public Department(String n){
name = n;
}
public void setName(String newName){
name = newName;
}
public String getName(){
return name;
}
public void addEmployee(Employee newEmployee){
employees.add(newEmployee);
// связываем сотрудника с этим отделом
newEmployee.setDepartment(this);
}
public Set getEmployees(){
return employees;
}
public void removeEmployee(Employee e){
employees.remove(e);
}
}
...
private Department department;
...
public void setDepartment(Department d){
department = d;
}
public Department getDepartment(){
return department;
}
Department programmersDepartment = new Department("Программисты");
programmersDepartment.addEmployee(sysEngineer);
System.out.println("Относится к отделу "+sysEngineer.getDepartment().getName());
private class PastPosition{
private String name;
private Department department;
public PastPosition(String position, Department dep){
name = position;
department = dep;
}
public void setName(String newName){
name = newName;
}
public String getName(){
return name;
}
public void setDepartment(Department d){
department = d;
}
public Department getDepartment(){
return department;
}
}
...
private Set pastPosition = new HashSet();
...
public void setPastPosition(PastPosition p){
pastPosition.add(p);
}
public Set getPastPosition(){
return pastPosition;
}
public void deletePastPosition(PastPosition p){
pastPosition.remove(p);
}
...
// изменяем должность
sysEngineer.setPosition("Сторож");
// смотрим ранее занимаемые должности:
System.out.println("В прошлом работал как:");
Iterator iter = sysEngineer.getPastPosition().iterator();
while(iter.hasNext()){
System.out.println( ((PastPosition) iter.next()).getName());
}
public class Menu{
private static int i=0;
public static void showEmployees(Employee[] employees){
System.out.println("Список сотрудников:");
for (i=0; i<employees.length; i++){
if(employees[i] instanceof Employee){
System.out.println(employees[i].getName() +" - " + employees[i].getPosition());
}
}
}
}
// добавим еще одного сотрудника
Employee director = new Employee("Федор", "Дубов", "Директор");
Menu menu = new Menu();
Employee employees[] = new Employee[10];
employees[0]= sysEngineer;
employees[1] = director;
Menu.showEmployees(employees);
public interface Unit{
int getPersonCount();
}
public class Department implements Unit{
...
public int getPersonCount(){
return getEmployees().size();
}
System.out.println("В отделе "+sysEngineer.getDepartment().getName()+" работает "
+sysEngineer.getDepartment().getPersonCount()+" человек.");
Язык моделирования UML имеет набор отношений для построения модели классов, но даже такой развитой ООП язык, как Java имеет только две явные конструкции для отражения связей: extends(расширение) и interface/implements(реализация).
В результате моделирования получили следующую диаграмму:
Рис. 8 — Диаграмма классов
Мини-справочник по обозначениям которые приняты в UML диаграммах классов для отношений между различными классами.
Обозначаются стрелками.
Самое обычное наследование: class A extends B { }
Реализация интерфейса: class A implements I { }
Семейство отношения между объектами классов. "Студент" - "Преподаватель", "Покупатель" - "Продавец" и т.д. Может обозначаться вообще без стрелки.
Агрегация и Композиция - подтипы ассоциации.
Подтип ассоциации. Например один класс содержит (агрегируют) объекты другого класса.
Похоже на агрегацию только более сильная связь. Поэтому закрашенный ромб. Например: если уничтожается композитор, то его объекты классов на которые он ссылается также перестают существовать.
Классы "каким либо образом" зависят друг от друга. Например, если у одного класса меняются методы, конструкторы или поля, и поэтому приходится переписывать другой класс, то значит они зависимы. Одна из самых слабеньких связей. Например объекты одного класса передаются как параметр в методы другого класса и т.д.
На этом все! Теперь вы знаете все про отношения классов в uml, Помните, что это теперь будет проще использовать на практике. Надеюсь, что теперь ты понял что такое отношения классов в uml и для чего все это нужно, а если не понял, или есть замечания, то не стесняйся, пиши или спрашивай в комментариях, с удовольствием отвечу. Для того чтобы глубже понять настоятельно рекомендую изучить всю информацию из категории Объектно-ориентированное программирование ООП
Комментарии
Оставить комментарий
Объектно-ориентированное программирование ООП
Термины: Объектно-ориентированное программирование ООП