Разложение животного мира
Я реализовал иерархию классов Mammal
в Java.
Является ли это разумным подходом к декомпозиции, локальности и процедурной абстракции?
package Hierarchies;
public class Mammals {
public Mammals(){
}
public void giveMilk(){
//REQUIRES: nothing
//MODIFIES: nothing
//EFFECTS : Display message of produce Milk
System.out.println("Produce milk to feed their babies.");
}
public void haveHair(){
//REQUIRES: nothing
//MODIFIES: nothing
//EFFECTS : Display message of Have Hair
System.out.println("Have hair on their bodies.");
}
}
public class Cats extends Mammals{
public Cats(){
}
public void Sounds(){
//REQUIRES: nothing
//MODIFIES: nothing
//EFFECTS : Display message of Sound
System.out.println("Meow Meow Meow!!!.");
}
public void Diet(){
//REQUIRES: nothing
//MODIFIES: nothing
//EFFECTS : Display message of Diet
System.out.println("Cats are Carnivores.");
}
}
public class Elephants extends Mammals {
public Elephants(){
}
public void Trunk(){
//REQUIRES: nothing
//MODIFIES: nothing
//EFFECTS : Display message of Have Trunk
System.out.println("Have Trunk.It functions for grasping, breathing, feeding, dusting, smelling, drinking.");
}
public void Diet(){
//REQUIRES: nothing
//MODIFIES: nothing
//EFFECTS : Display message of Diet
System.out.println("Elephants are Herbivorous.");
}
}
public class Dogs extends Mammals {
public Dogs(){
}
public void Bark(){
//REQUIRES: nothing
//MODIFIES: nothing
//EFFECTS : Display message of Bark
System.out.println("Woo Woo!!!.");
}
public void Diet(){
//REQUIRES: nothing
//MODIFIES: nothing
//EFFECTS : Display message of Diet
System.out.println("Dogs are Omnivores.");
}
}
public class Sporting extends Dogs {
public Sporting(){
}
public void Race(){
//REQUIRES: nothing
//MODIFIES: nothing
//EFFECTS : Display message of purpose for which they used
System.out.println("Used For Reacing Purposes.");
}
}
public class Working extends Dogs {
public Working(){
}
public void work(){
//REQUIRES: nothing
//MODIFIES: nothing
//EFFECTS : Display message of work they done
System.out.println("Learns and performs tasks to assist and entertain its human companions.");
}
}
public class Pet extends Dogs {
public Pet(){
}
public void Work(){
//REQUIRES: nothing
//MODIFIES: nothing
//EFFECTS : Display message of work they done
System.out.println(" Commonly provide their owners physical and emotional benefits.");
}
}
public class Hunting extends Dogs {
public Hunting(){
}
public void Work(){
//REQUIRES: nothing
//MODIFIES: nothing
//EFFECTS : Display message for their work
System.out.println(" Hunting dog refers to a canine that hunts with or for humans.");
}
}
public class WolfHound extends Hunting {
public WolfHound(){
}
public void Task(){
//REQUIRES: nothing
//MODIFIES: nothing
//EFFECTS : Display message of task they done
System.out.println(" The breed was originally developed from war hounds to one used for hunting and guarding.");
}
}
public class FoxHound extends Hunting {
public FoxHound(){
}
public void Task(){
//REQUIRES: nothing
//MODIFIES: nothing
//EFFECTS : Display message of task they done
System.out.println(" A foxhound is a type of large hunting hound bred for strong hunting instincts, great energy, and, like all scent hounds, a keen sense of smell.");
}
}
Основной метод
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner input=new Scanner(System.in);
Mammals mam= new Mammals();
Dogs dog= new Dogs();
Cats cat=new Cats();
Elephants elep=new Elephants();
Sporting sport=new Sporting();
Working work= new Working();
Pet pet=new Pet();
Hunting hunt=new Hunting();
WolfHound wolf=new WolfHound();
FoxHound fox =new FoxHound();
System.out.println("Welcome to Mammals Class !!!");
System.out.println("1-Dogs ");
System.out.println("2-Cats ");
System.out.println("3-Elephants ");
System.out.println("Enter the Number To which Mamamal Class You GO ");
int choice=input.nextInt();
switch(choice){
case 1:
System.out.println("1- Sporting ");
System.out.println("2- Working ");
System.out.println("3- Pet ");
System.out.println("4- Hunting ");
int choice2=input.nextInt();
switch(choice2){
case 1:
sport.giveMilk();
sport.haveHair();
sport.Bark();
sport.Diet();
sport.Race();
break;
case 2:
work.giveMilk();
work.haveHair();
work.Bark();
work.Diet();
work.work();
break;
case 3:
pet.giveMilk();
pet.haveHair();
pet.Bark();
pet.Diet();
pet.Work();
break;
case 4:
System.out.println("1- WolfHound ");
System.out.println("2- FoxHound ");
int choice3=input.nextInt();
switch(choice3){
case 1:
wolf.giveMilk();
wolf.haveHair();
wolf.Bark();
wolf.Diet();
wolf.Task();
wolf.Work();
break;
case 2:
fox.giveMilk();
fox.haveHair();
fox.Bark();
fox.Diet();
fox.Work();
fox.Task();
break;
default:
System.out.println("Invalid Choice");
break;
}
break;
default:
System.out.println("Invalid Choice");
break;
}
break;
case 2:
cat.giveMilk();
cat.haveHair();
cat.Diet();
cat.Sounds();
break;
case 3:
elep.giveMilk();
elep.haveHair();
elep.Diet();
elep.Trunk();
break;
default:
System.out.println("Invalid Choice");
break;
}
}
}
2 ответа
Резюме
- Используйте уникальные имена классов.
- При необходимости используйте наследование.
- Следуйте правилам кода.
- Будьте в курсе грамматики.
- Напишите короткие методы.
Использовать Singular для имен классов
Используйте имя, которое представляет собой один объект, а не всю группу. То есть change Dogs
до Dog
.
Исключение составляют классы утилиты, то есть класс утилиты для массивов называется Arrays
, класс утилиты для коллекций называется Collections
. Невозможно создать объекты служебных классов (они предотвращают это путем перечисления нулевого элемента или класса с частным конструктором).
Однако ваши классы не являются служебными классами. Поэтому используйте сингулярное число.
Соответствующее наследование
Наследование подходит, если подкласс наследует все или почти все черты суперкласса.
Не каждое существительное - класс!
Существительные не всегда являются классами, они также могут быть атрибутами. Домашним животным является такой пример. И собака, и кот могут быть домашним животным. На самом деле, любое животное может быть домашним животным. Домашнее животное - гораздо более подробное описание отношений между владельцем животного и животным.
В вашей модели все ваши классы, которые описывают роли, вероятно, просто будут переменными, а не классами.
Имейте в виду, что на языке, подобном Java, и большинству (но не во всех) языках программирования, объект не может изменить свой класс в течение своей жизни. Собака собака собака и остается собакой, даже если она становится домашним животным, охотится и так далее. Это должен быть один и только один объект, достигающий всех этих вещей.
Иногда, конечно, имеет смысл создавать классы для ролей. У вас может быть class Pet
. Но в этом случае Pet
не должен быть подклассом этих других классов, например class Dog
. Вместо этого вы должны использовать делегирование /состав, например:
class Pet {
Animal animal;
}
Затем class Pet
описывает роль, и эта роль может выполняться любым типом животного.
Предпочитают состав над наследованием.
Это не всегда подходит, но вам может быть интересно узнать, что это значит. Наследование действительно чрезмерно используется. И наследование, в отличие от некоторых людей, кажется, не в основе объектно-ориентированных языков программирования. На самом деле существуют языки программирования, которые мы счастливо называем объектно-ориентированными, которые вообще не поддерживают этот простой «расширяет» тип наследования. В качестве примера можно привести JavaScript.
Условные обозначения кода
В Java соглашение должно начинать имена методов в нижнем регистре. Измените Task()
на task()
, Sounds()
до sounds()
и т. Д.
Использовать правильную и последовательную грамматику
Иногда вы используете форму нормального глагола, то есть giveMilk()
, иногда вы используете форму третьего лица, то есть sounds()
. Быть последовательным. Обычно в Java всегда использовать форму нормального глагола, а не форму третьего лица, в коде. И в комментариях, обычно в Java всегда используется форма третьего лица, за исключением случаев, когда вы напрямую обращаетесь к читателю.
Короткие методы
Ваш метод main()
слишком длинный. Хорошие размеры метода похожи на 3-4 строки, иногда 5, только в редких ситуациях немного больше.
Метод должен делать только одно, он должен делать это хорошо, и он должен делать это только. (Роберт К. Мартин)
Итак, подумайте о том, как разбить метод main()
на кучу меньших методов.
Здесь многое продолжается. Вы должны рассмотреть возможность использования интерфейсов, особенно учитывая добавление методов по умолчанию в Java 8. Кроме того, некоторые из ваших имен классов странны:
Sporting extends Dog
иWorking extends Dog
, вероятно, поразит всех зрителей как необычное. SportsDog
и WorkDog
будет лучше, чем класс но, опять же, вместо того, чтобы ограничивать себя через наследование, я предлагаю вам использовать интерфейс на своем месте.
Посмотрим, как это будет выглядеть, используя некоторые из ваших классов.
Класс млекопитающих имеет смысл, но вы определенно не хотите, чтобы что-то было только млекопитающим? Если мы хотим обеспечить определенность, такой класс должен быть аннотация . Теперь класс собак и котов, которые расширяют класс млекопитающих, также имеет смысл, но класс для домашних животных, расширяющий Собака ... и многие животные могут быть домашними животными, а что, если вы хотите, чтобы кошка была домашним животным? Вместо этого это будет интерфейс!
public interface Domesticable {
default void provideFriendship() {
System.out.println("Gives love to owner");
}
}
Я добавил метод по умолчанию, чтобы проиллюстрировать новую функцию, но если вы используете что-либо ниже, чем Java 8, вы должны писать только подпись метода без реализации и должны использовать Ovverride все методы интерфейса в любых классах реализации (что вы все равно можете сделать в этом случае, например, provideFriendship()
, чтобы кошка могла указывать «скручиваясь вокруг ноги хозяина»). Подумайте о интерфейсах как контрактах, которые должен соблюдать класс.
Итак, если вы это сделали, ваш класс Dog будет больше похож:
Class Dog extends Mammal implements Domesticable
, и вы можете сделать то же самое для любого животного, которое вы хотите получить в качестве домашнего животного.
Попробуйте определить, где еще вы можете использовать интерфейс. Помните, что в отличие от Inheritance, который ограничен одним классом, вы можете реализовать несколько интерфейсов.
So
Pig extends Mammal implements Domesticable, Comparable, Edible
является совершенно законным.