차고에 차가 있습니까? [복제]
이 질문에는 이미 답변이 있습니다.
Java 프로그래밍에 익숙하지 않아 OOP를 중단하려고합니다.
그래서 나는이 추상 클래스를 만들었습니다.
public abstract class Vehicle{....}
그리고 2 개의 서브 클래스 :
public class Car extends Vehicle{....}
public class Boat extends Vehicle{....}
Car
그리고 Boat
또한 몇 가지 독특한 분야 공통없는 방법을 개최 (나는 자동차에 그들을 위해 추상적 인 방법을 정의 할 수 있도록, 같은 이름이 없습니다).
이제 mainClass에서 새로운 차고를 설정했습니다.
Vehicle[] myGarage= new Vehicle[10];
myGarage[0]=new Car(2,true);
myGarage[1]=new Boat(4,600);
다음과 같이 Car 고유의 필드 중 하나에 액세스하려고 할 때까지 다형성에 매우 만족했습니다.
boolean carIsAutomatic = myGarage[0].auto;
컴파일러는이를 받아들이지 않습니다. 캐스팅을 사용 하여이 문제를 해결했습니다.
boolean carIsAutomatic = ((Car)myGarage[0]).auto;
그것은 작동하지만 ... 방법, 필드에만 도움이되지 않습니다. 할 수 없다는 의미
(Car)myGarage[0].doSomeCarStuff();
내 질문은-차고에 실제로 무엇을 가지고 있습니까? 나는 직관을 얻으려고 노력하고 있으며, "장면"에서 무슨 일이 일어나고 있는지 이해하려고 노력하고 있습니다.
미래 독자들을 위해 아래 답변에 대한 간략한 요약 :
- 네, 거기
Car
에myGarage[]
- 정적 타입 언어이기 때문에 Java 컴파일러는 Vehicle 슈퍼 클래스 (와 같은
Vehicle myGarage[]
) 에 기반한 데이터 구조를 통해 접근 할 경우 "비히클"이 아닌 메소드 / 필드에 액세스 할 수 없습니다. - 해결 방법은 다음과 같은 두 가지 주요 접근 방식이 있습니다.
- 유형 캐스팅을 사용하면 컴파일러의 문제가 완화되고 런타임시 디자인에 오류가 남습니다.
- 주조가 필요하다는 사실은 디자인에 결함이 있다고 말합니다. 비 차량 기능에 액세스해야하는 경우 차량 기반 데이터 구조에 자동차 및 보트를 저장해서는 안됩니다. 이러한 모든 기능을 차량에 속하게하거나보다 구체적인 (유도 된) 유형 기반 구조를 사용하십시오.
- 많은 경우 컴포지션 및 / 또는 인터페이스가 상속에 대한 더 나은 대안이 될 수 있습니다. 아마도 내 다음 질문의 주제는 ...
- 답변을 찾아 볼 시간이 있다면 다른 많은 좋은 통찰력을 얻을 수 있습니다.
당신이 사이의 차이를해야 할 경우 Car
와 Boat
당신의 차고에, 당신은 별개의 구조에 저장해야합니다.
예를 들어 :
public class Garage {
private List<Car> cars;
private List<Boat> boats;
}
그런 다음 보트 또는 자동차에 특정한 방법을 정의 할 수 있습니다.
그러면 왜 다형성이 있습니까?
다음 Vehicle
과 같이 말하십시오 .
public abstract class Vehicle {
protected int price;
public getPrice() { return price; }
public abstract int getPriceAfterYears(int years);
}
모든 클래스 Vehicle
에는 가격이 있으므로 Vehicle
추상 클래스 안에 넣을 수 있습니다 .
그러나 n 년 후 가격을 결정하는 공식은 차량에 따라 다르므로이를 정의하기 위해 구현 클래스로 남겨졌습니다. 예를 들어 :
public Car extends Vehicle {
// car specific
private boolean automatic;
@Override
public getPriceAfterYears(int years) {
// losing 1000$ every year
return Math.max(0, this.price - (years * 1000));
}
}
Boat
클래스에 대한 다른 정의가있을 수 있습니다 getPriceAfterYears
특정의 속성과 메소드와.
이제 Garage
클래스로 돌아가서 다음을 정의 할 수 있습니다.
// car specific
public int numberOfAutomaticCars() {
int s = 0;
for(Car car : cars) {
if(car.isAutomatic()) {
s++;
}
}
return s;
}
public List<Vehicle> getVehicles() {
List<Vehicle> v = new ArrayList<>(); // init with sum
v.addAll(cars);
v.addAll(boats);
return v;
}
// all vehicles method
public getAveragePriceAfterYears(int years) {
List<Vehicle> vehicules = getVehicles();
int s = 0;
for(Vehicle v : vehicules) {
// call the implementation of the actual type!
s += v.getPriceAfterYears(years);
}
return s / vehicules.size();
}
다형성의 관심은 전화를 할 수있다 getPriceAfterYears
켜짐 Vehicle
없이 구현에 대한 배려입니다.
일반적으로 다운 캐스팅은 결함이있는 디자인의 징조입니다. 실제 유형을 구별해야하는 경우 차량을 모두 함께 보관하지 마십시오.
참고 : 물론 여기의 디자인을 쉽게 향상시킬 수 있습니다. 요점을 보여주는 예일뿐입니다.
당신의 질문에 대답하기 위해 당신은 당신의 차고에 정확히 무엇이 있는지 알아낼 수 있습니다.
Vehicle v = myGarage[0];
if (v instanceof Car) {
// This vehicle is a car
((Car)v).doSomeCarStuff();
} else if(v instanceof Boat){
// This vehicle is a boat
((Boat)v).doSomeBoatStuff();
}
업데이트 : 아래 의견에서 읽을 수 있듯이이 방법은 간단한 솔루션에는 적합하지만 특히 차고에 많은 수의 차량이있는 경우 좋은 방법은 아닙니다. 차고가 작게 유지 될 경우에만 사용하십시오. 그렇지 않은 경우 스택 오버플로에서 "Avoiding instanceof"를 검색하면 여러 가지 방법이 있습니다.
기본 유형으로 작업하는 경우 공용 메소드 및 필드에만 액세스 할 수 있습니다.
확장 유형에 액세스하고 싶지만 기본 유형의 필드가 저장되어있는 경우 (경우와 같이) 먼저 캐스팅 한 다음 액세스 할 수 있습니다.
Car car = (Car)myGarage[0];
car.doSomeCarStuff();
또는 임시 필드없이 짧게 :
((Car)myGarage[0]).doSomeCarStuff();
Vehicle
객체 를 사용하고 있으므로 캐스팅하지 않고 기본 클래스의 메소드 만 호출 할 수 있습니다. 따라서 차고의 경우 다른 배열 또는 더 나은 목록의 객체를 구별하는 것이 좋습니다. 배열은 Collection
기반 클래스 보다 처리가 훨씬 유연하지 않기 때문에 종종 좋은 생각이 아닙니다 .
당신은 당신의 차고가 차량을 저장하도록 정의했기 때문에 어떤 종류의 차량을 가지고 있든 상관 없습니다. 차량에는 엔진, 휠, 움직이는 것과 같은 행동과 같은 공통된 기능이 있습니다. 이러한 기능의 실제 표현은 다를 수 있지만 추상 레이어에서는 동일합니다. 추상 클래스를 사용했습니다. 이는 일부 속성, 동작이 두 차량에서 정확히 동일하다는 것을 의미합니다. 차량에 공통의 추상 기능이 있다고 표현하려면 이동과 같은 인터페이스를 사용하면 자동차와 보트에 따라 다를 수 있습니다. 둘 다 지점 A에서 지점 B로 갈 수 있지만 다른 방법으로 (바퀴 또는 물에서-구현이 다를 수 있음) 차고에 동일한 방식으로 작동하는 차량이 있으며 특정 기능에 대해 자동차를 운전하지 않습니다 그들의.
주석에 대답하려면 다음을 수행하십시오.
인터페이스는 외부 세계와 통신하는 방법을 설명하는 계약을 의미합니다. 계약에서는 차량이 움직일 수 있고 조종 할 수 있지만 실제로 어떻게 작동하는지 설명하지는 않지만 구현에 설명되어 있습니다. 추상 클래스를 통해 구현을 공유하는 기능이있을 수 있지만 구현 방법을 모르는 기능.
추상 클래스를 사용하는 예 :
abstract class Vehicle {
protected abstract void identifyWhereIAm();
protected abstract void startEngine();
protected abstract void driveUntilIArriveHome();
protected abstract void stopEngine();
public void navigateToHome() {
identifyWhereIAm();
startEngine();
driveUntilIArriveHome();
stopEngine();
}
}
각 차량마다 동일한 단계를 사용하지만 단계 구현은 차량 유형에 따라 다릅니다. 자동차는 GPS를, 보트는 소나를 사용하여 위치를 식별 할 수 있습니다.
Java 프로그래밍에 익숙하지 않아 OOP를 중단하려고합니다.
내 2 센트 만 – 이미 많은 흥미로운 것들이 언급 된대로 짧게 만들려고합니다. 그러나 실제로 여기에는 두 가지 질문이 있습니다. 하나는 "OOP"에 관한 것이고 다른 하나는 Java에서 어떻게 구현되는지에 관한 것입니다.
우선, 그래, 당신 이 당신의 차고에서 차를. 따라서 당신의 가정은 옳습니다. 그러나 Java는 정적으로 유형이 지정된 언어입니다. 그리고 컴파일러의 타입 시스템은 해당 선언에 의해서만 다양한 객체의 타입을 "인식"할 수 있습니다 . 사용법이 아닙니다. 의 배열이 있으면 Vehicle
컴파일러는이를 알고 있습니다. 따라서 모든에서 허용 된 작업 만 수행하는지 확인 합니다Vehicle
. 즉, 선언 에서 볼 수있는 메소드 및 속성Vehicle
입니다.
당신은 컴파일러로 설명 할 수있다 "는 사실이 알려 Vehicle
A는 Car
" 명시 적 캐스트를 사용하여 (Car)
. 컴파일러는 Java 에서 런타임 검사가 있어도 거짓말ClassCastException
을하면 추가 손상을 방지 할 수 있습니다 (C ++과 같은 다른 언어는 런타임에 검사하지 않습니다). 당신이하는 일)
마지막으로, 실제로 필요한 경우 런타임 유형 식별 (예 instanceof
:)을 사용하여 오브젝트를 캐스트하기 전에 "실제"유형의 오브젝트를 점검 할 수 있습니다. 그러나 이것은 대부분 Java에서 나쁜 습관으로 간주됩니다.
내가 말했듯이, 이것은 OOP를 구현하는 Java 방식입니다. 완전히 다르다수업 가족 널리 알려진 언어의 "동적 언어" , 단지 런타임에 확인 작업이 개체에서 허용되지 않습니다. 이러한 언어를 사용하면 유형 시스템을 만족시키기 위해 모든 공통 메소드를 일부 (아마도 추상적 인) 기본 클래스로 "이동"할 필요가 없습니다. 이것을 오리 타이핑 이라고 합니다.
당신은 당신의 집사에게 물었습니다 :
Jeeves, Java 섬의 차고 기억 나? 주차 한 첫 번째 차량이 자동인지 확인하십시오.
게으른 Jeeves는 말했다 :
그러나 자동 또는 비 자동이 될 수없는 차량이라면 어떨까요?
그게 다야.
현실이 정적으로 타이핑되는 것보다 더 오리 타입이기 때문에 그다지 전부는 아닙니다. 그래서 Jeeves가 게으르다 고 말했습니다.
여기서 문제는 더 근본적인 수준입니다. 인터페이스가 제공하는 것보다 객체에 대해 더 많이 알아야 Vehicle
하는 방식으로 구축 했습니다 . 당신은 관점에서 (그리고 일반적으로 사용할 모든 것의 관점에서) 클래스를 만들려고 노력해야합니다 . 그들은 차량과 어떤 종류의 일을해야합니까? 내 방법으로 어떻게 그런 것들을 가능하게 할 수 있습니까?Garage
Vehicle
Vehicle
Garage
Vehicle
예를 들어, 귀하의 예에서 :
bool carIsAutomatic = myGarage[0].auto;
차고에서 ... 차량 엔진에 대해 알고 싶은 이유는 무엇입니까? 어쨌든 이것에 의해 노출 될 필요는 없습니다 Car
. 에 구현되지 않은 isAutomatic()
메소드를 계속 노출 한 Vehicle
다음 return True
in Boat
및 return this.auto
in 로 구현할 수 Car
있습니다.
그것은 세 가지 값 가지고 더 나은 것 EngineType
열거 ( HAS_NO_GEARS
, HAS_GEARS_AUTO_SHIFT
, HAS_GEARS_MANUAL_SHIFT
일반의 실제 특성에 대한 코드 이유하자 것이다,) Vehicle
깨끗하게하고 정확하게합니다. (어쨌든 오토바이를 다루려면이 구분이 필요합니다.)
차고에는 Vehicles가 포함되어 있으므로 Vehicle이있는 컴파일러 정적 제어 뷰이며 .auto는 액세스 할 수없는 Car 필드이므로 동적으로 Car이므로 캐스트는 문제가 발생하지 않습니다. 보트와 자동차에 캐스트하려고하면 런타임에 예외가 발생합니다.
이것은 Visitor
디자인 패턴 을 적용하기에 좋은 장소입니다 .
이 패턴의 장점은 어디에서나 이상한 캐스트를 수행하거나 수 많은 관련없는 메소드를 수퍼 클래스에 넣지 않고도 수퍼 클래스의 여러 서브 클래스에서 관련없는 코드를 호출 할 수 있다는 것입니다.
이것은 Visitor
객체 를 만들고 Vehicle
클래스를 accept()
방문자 에게 허용 하여 작동합니다 .
Visitor
동일한 메소드를 사용하여 여러 유형을 작성 하고 관련이없는 코드를 호출 할 수 있습니다 . 단지 다른 Visitor
구현으로, 깨끗한 클래스를 작성할 때이 디자인 패턴을 매우 강력하게 만듭니다.
예를 들어 데모 :
public class VisitorDemo {
// We'll use this to mark a class visitable.
public static interface Visitable {
void accept(Visitor visitor);
}
// This is the visitor
public static interface Visitor {
void visit(Boat boat);
void visit(Car car);
}
// Abstract
public static abstract class Vehicle implements Visitable {
// NO OTHER RANDOM ABSTRACT METHODS!
}
// Concrete
public static class Car extends Vehicle {
public void doCarStuff() {
System.out.println("Doing car stuff");
}
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
}
// Concrete
public static class Boat extends Vehicle {
public void doBoatStuff() {
System.out.println("Doing boat stuff");
}
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
}
// Concrete visitor
public static class StuffVisitor implements Visitor {
@Override
public void visit(Boat boat) {
boat.doBoatStuff();
}
@Override
public void visit(Car car) {
car.doCarStuff();
}
}
public static void main(String[] args) {
// Create our garage
Vehicle[] garage = {
new Boat(),
new Car(),
new Car(),
new Boat(),
new Car()
};
// Create our visitor
Visitor visitor = new StuffVisitor();
// Visit each item in our garage in turn
for (Vehicle v : garage) {
v.accept(visitor);
}
}
}
보시다시피, StuffVisitor
호출 구현에 따라 Boat
또는 다른 코드를 호출 할 수 있습니다 . 동일한 패턴으로 다른 코드를 호출하기 위해 방문자의 다른 구현을 작성할 수도 있습니다 .Car
visit
.visit()
또한이 방법을 사용하면 instanceof
해키 클래스 검사가 사용되지 않습니다 . 클래스간에 유일한 중복 코드는 메서드 void accept(Visitor)
입니다.
예를 들어 3 가지 유형의 구체적 서브 클래스를 지원하려면 해당 구현을 Visitor
인터페이스에 추가하면 됩니다.
나는 실제로 다른 사람들의 아이디어를 여기에 모으고 있습니다 (그리고 나는 Java 사람이 아니기 때문에 이것이 실제가 아닌 의사입니다).이 고안된 예에서는 내 차 점검 방식을 전용 클래스로 추상화 할 것입니다. 차를 볼 때 차에 대해서만 알고 차에 대해서만 관심을 갖습니다.
abstract class Vehicle {
public abstract string getDescription() ;
}
class Transmission {
public Transmission(bool isAutomatic) {
this.isAutomatic = isAutomatic;
}
private bool isAutomatic;
public bool getIsAutomatic() { return isAutomatic; }
}
class Car extends Vehicle {
@Override
public string getDescription() {
return "a car";
}
private Transmission transmission;
public Transmission getTransmission() {
return transmission;
}
}
class Boat extends Vehicle {
@Override
public string getDescription() {
return "a boat";
}
}
public enum InspectionBoolean {
FALSE, TRUE, UNSUPPORTED
}
public class CarInspector {
public bool isCar(Vehicle v) {
return (v instanceof Car);
}
public bool isAutomatic(Car car) {
Transmission t = car.getTransmission();
return t.getIsAutomatic();
}
public bool isAutomatic(Vehicle vehicle) {
if (!isCar(vehicle)) throw new UnsupportedVehicleException();
return isAutomatic((Car)vehicle);
}
public InspectionBoolean isAutomatic(Vehicle[] garage, int bay) {
if (!isCar(garage[bay])) return InspectionBoolean.UNSUPPORTED;
return isAutomatic(garage[bay])
? InspectionBoolean.TRUE
: InspectionBoolean.FALSE;
}
}
요점은, 당신은 이미 당신이 자동차의 변속기에 대해 질문 할 때 자동차에 대해서만 관심을 갖기로 결정했다는 것입니다. CarInspector에 문의하십시오. Tri-State Enum 덕분에 이제 자동인지 아니면 자동차가 아닌지 알 수 있습니다.
물론, 관심있는 차량마다 다른 차량 검사기가 필요합니다. 그리고 어떤 VehicleInspector가 체인을 인스턴스화해야하는지에 대한 문제를 방금 추진했습니다.
대신 인터페이스를 살펴볼 수 있습니다.
getTransmission
인터페이스로 추상화하십시오 (예 :) HasTransmission
. 이렇게하면 차량에 변속기가 있는지 확인하거나 TransmissionInspector를 작성할 수 있습니다.
abstract class Vehicle { }
class Transmission {
public Transmission(bool isAutomatic) {
this.isAutomatic = isAutomatic;
}
private bool isAutomatic;
public bool getIsAutomatic() { return isAutomatic; }
}
interface HasTransmission {
Transmission getTransmission();
}
class Car extends Vehicle, HasTransmission {
private Transmission transmission;
@Override
public Transmission getTransmission() {
return transmission;
}
}
class Bus extends Vehicle, HasTransmission {
private Transmission transmission;
@Override
public Transmission getTransmission() {
return transmission;
}
}
class Boat extends Vehicle { }
enum InspectionBoolean {
FALSE, TRUE, UNSUPPORTED
}
class TransmissionInspector {
public bool hasTransmission(Vehicle v) {
return (v instanceof HasTransmission);
}
public bool isAutomatic(HasTransmission h) {
Transmission t = h.getTransmission();
return t.getIsAutomatic();
}
public bool isAutomatic(Vehicle v) {
if (!hasTranmission(v)) throw new UnsupportedVehicleException();
return isAutomatic((HasTransmission)v);
}
public InspectionBoolean isAutomatic(Vehicle[] garage, int bay) {
if (!hasTranmission(garage[bay])) return InspectionBoolean.UNSUPPORTED;
return isAutomatic(garage[bay])
? InspectionBoolean.TRUE
: InspectionBoolean.FALSE;
}
}
이제는 차량에 관계없이 전송에 대해서만 말하고 있으므로 TransmissionInspector에 요청할 수 있습니다. 버스와 자동차는 TransmissionInspector로 검사 할 수 있지만 전송에 대해서만 물어볼 수 있습니다.
이제 부울 값만 신경 쓰지 않아도됩니다. 이때 지원되는 상태와 값을 모두 노출하는 일반 지원 유형을 사용하는 것이 좋습니다.
class Supported<T> {
private bool supported = false;
private T value;
public Supported() { }
public Supported(T value) {
this.isSupported = true;
this.value = value;
}
public bool isSupported() { return supported; }
public T getValue() {
if (!supported) throw new NotSupportedException();
return value;
}
}
이제 검사기는 다음과 같이 정의 될 수 있습니다.
class TransmissionInspector {
public Supported<bool> isAutomatic(Vehicle[] garage, int bay) {
if (!hasTranmission(garage[bay])) return new Supported<bool>();
return new Supported<bool>(isAutomatic(garage[bay]));
}
public Supported<int> getGearCount(Vehicle[] garage, int bay) {
if (!hasTranmission(garage[bay])) return new Supported<int>();
return new Supported<int>(getGearCount(garage[bay]));
}
}
내가 말했듯이, 나는 자바 사람이 아니므로 위의 구문 중 일부는 잘못되었을 수 있지만 개념은 유지되어야합니다. 그럼에도 불구하고, 먼저 테스트하지 않고 중요한 곳을 실행하지 마십시오.
Java를 사용하는 경우 리플렉션을 사용하여 함수가 사용 가능한지 확인하고 실행할 수도 있습니다.
각 개별 차량을보다 명확하게 만드는 차량 레벨 필드를 만듭니다 .
public abstract class Vehicle {
public final boolean isCar;
public final boolean isBoat;
public Vehicle (boolean isCar, boolean isBoat) {
this.isCar = isCar;
this.isBoat = isBoat;
}
}
설정 적절한 값으로 상속 클래스의 차량 레벨 필드.
public class Car extends Vehicle {
public Car (...) {
super(true, false);
...
}
}
public class Boat extends Vehicle {
public Boat (...) {
super(false, true);
...
}
}
구현 이 제대로 암호문 해독 차량 유형으로 차량 레벨 필드를 사용하여.
boolean carIsAutomatic = false;
if (myGarage[0].isCar) {
Car car = (Car) myGarage[0];
car.carMethod();
carIsAutomatic = car.auto;
}
else if (myGarage[0].isBoat) {
Boat boat = (Boat) myGarage[0];
boat.boatMethod();
}
컴파일러에게 차고의 모든 것이 비히클이라는 것을 알려주기 때문에 비히클 클래스 레벨의 메소드와 필드를 고수했습니다. 제대로 암호문 해독 차량 유형 원하는 경우에, 당신은 몇 가지 클래스 수준 필드 예를 들어 설정해야 isCar
하고 isBoat
그게 당신이 사용하는 차량의 종류의 이해 더 나은 당신에게 프로그래머를 줄 것이다.
Java는 형식이 안전한 언어이므로 Boat
S 및 Car
S 처럼 캐스트 된 데이터를 처리하기 전에 항상 형식을 확인하는 것이 가장 좋습니다 .
어떤 문제를 해결하기 위해 프로그램에 제시하고자하는 객체를 모델링하는 것이 중요합니다. 코딩은 또 다른 이야기입니다. 귀하의 코드에서 본질적으로 배열을 사용하여 차고를 모델링하는 것은 부적절하다고 생각합니다. 배열은 그들이 않지만 종종 개체로 간주되어서는 안됩니다 표시 보통의 자체 포함 다움 종류의 위해, 수 무결성 언어의 일부 친숙 함을 제공하지만 형식으로 배열 정말 그냥 컴퓨터 고유 IMHO, 특히 Java에서는 배열을 확장 할 수 없습니다.
차고를 나타내는 클래스를 올바르게 모델링해도 "차고의 자동차"질문에 대답하는 데 도움이되지 않는다는 것을 이해합니다. 충고 한 조각.
코드로 돌아가십시오. OOP에 매달린 것 외에, 몇 가지 질문은 장면을 만드는 데 도움이되므로 해결하려는 문제를 더 잘 이해하는 데 도움이 될 것입니다 ( "일부 중단"이 아니라 가정).
- 누구 또는 무엇을 이해하고 싶
carIsAutomatic
습니까? - 을 감안할 때
carIsAutomatic
, 누구 또는 무엇을 수행 할 것doSomeCarStuff
?
일부 검사관 또는 자동 변속기 자동차 등을 운전하는 방법 만 아는 사람 일 수 있지만 차고의 관점에서 볼 때 모든 차량을 보유하고 있다는 것만 알고 있으므로 (이 모델에서는)이 검사관의 책임입니다 또는 자동차인지 보트인지를 알려주는 운전자; 이 시점에서 씬에서 비슷한 유형의 * actor *를 나타내는 또 다른 클래스 묶음을 생성 할 수 있습니다. 해결해야 할 문제에 따라 실제로 필요한 경우 차고를 슈퍼 지능형 시스템으로 모델링 할 수 있으므로 일반 차고 대신 자동 판매기처럼 작동합니다. 사람들이 원하는대로 버튼을 눌러 자동차 나 보트를 얻을 수 있도록 "보트" 이 슈퍼 지능형 차고는 사용자에게 무엇을 제시해야 하는지를 알려줄 책임이 있습니다. 이 즉흥 연습을 따르기 위해 차고가 차량을 수령 할 때 약간의 부기가 필요할 수도 있고, 누군가가 정보를 제공해야 할 수도 있습니다.메인 클래스.
OO 프로그램을 코딩하기 위해 보일러 플레이트와 함께 모든 문제를 이해합니다. 특히 문제를 해결하려고 할 때 매우 간단하지만 OO는 실제로 다른 많은 문제를 해결할 수있는 방법입니다. 내 경험에 따르면, 사용 사례를 제공하는 일부 입력을 통해 사람들은 객체가 서로 상호 작용하는 방식을 장면을 디자인하고 클래스 (Java의 인터페이스뿐만 아니라)로 분류 한 다음 Main 클래스 와 같은 것을 사용 하여 세계 를 부트 스트랩합니다 .
참고 URL : https://stackoverflow.com/questions/24883075/do-i-really-have-a-car-in-my-garage
'IT' 카테고리의 다른 글
git (버전 제어)에서 데이터베이스를 어떻게 배치 할 수 있습니까? (0) | 2020.03.31 |
---|---|
“int main () {(([] () {}) ());}”은 어떻게 C ++에 유효합니까? (0) | 2020.03.31 |
젠킨스 vs 트래비스 CI. (0) | 2020.03.31 |
자바 스크립트 파일 이름 명명 규칙은 무엇입니까? (0) | 2020.03.31 |
파일을 열면 실제로 무엇을합니까? (0) | 2020.03.31 |