2012-03-02 21 views
6

Tak więc, w szkole mamy zlecenie na wykonanie samochodu w OOP, do tej pory było to łatwe i proste. Ale teraz muszę utworzyć cztery konstruktory, jeden bez parametrów, dwa z jednym parametrem i jeden z dwoma parametrami.Wiele konstruktorów z jednym parametrem

O ile mi wiadomo, sposób przeciążania działa, ponieważ sprawdza ilość parametrów, które dostarczasz, a następnie sprawdza, który z nich musi użyć. Ponieważ dwa konstruktory są takie same, oba akceptują ints, tylko jeden musi zmienić ilość lub narzędzia, a drugi musi zmienić maksymalną prędkość.

Czy można to zrobić bez dodatkowego parametru?

+0

Myślę, że błędnie przeczytałeś zadanie: dlaczego miałbyś przekazywać liczbę biegów (liczbę) lub maksymalną prędkość (także liczbę) jako ciąg? Ale ta obserwacja niekoniecznie rozwiązuje problem. Twoje wątpliwości są zasadniczo poprawne - wątpliwe jest, czy dobry projekt OOP używałby tutaj konstruktorów. –

+0

Czy Twoje * zadanie * umożliwia korzystanie z konstruktorów, czy też to * Twój sposób rozwiązywania * konkretnego zadania? –

+0

Wygląda na to, że brzmi to niejednoznacznie. Nie jestem pewien, czy to możliwe. –

Odpowiedz

12

O ile mi wiadomo, sposób przeciążania działa polega na sprawdzeniu ilości parametrów, które mu dostarczasz, a następnie sprawdza, który z nich musi użyć.

Nie, przeciążanie nie opiera się wyłącznie na liczby parametrów - to na podstawie ich typów też.

Jednakże:

W dwóch konstruktorów są takie same, zarówno akceptuje ciągi

To jest problem. Nie można zadeklarować dwóch konstruktorów tak:

public Foo(string x) 
{ 
} 

public Foo(string y) 
{ 
} 

podpisy te spotkania miarę przeciążenie jest zaniepokojony.

Proponuję o publiczne statycznych metod fabrycznych, tak można określić to, co starasz się stworzyć:

public static Foo FromGears(string gears) 
{ 
    return new Foo(...); 
} 

public static Foo FromMaximumSpeed(string maxSpeed) 
{ 
    return new Foo(...); 
} 

Można by wtedy ewentualnie mieć jeden konstruktor, który przyjął obie wartości i domyślny, którykolwiek z nich brakuje, gdy wywołujesz konstruktora z metody fabryki.

Jednak istnieją dwa inne osobliwości w opisie:

  • Używasz ciągi dla dwóch wartości, które brzmią tak, jak powinny one być numery (ewentualnie jeden numer i jeden Number i -jednostka)
  • Mówisz o deklarowaniu konstruktorów, ale używasz słowa "zmień" tak, jakby zamierzały zmienić istniejącą instancję. To nie ma sensu - konstruktorzy służą do tworzenia obiektów nowych.

EDIT: Ok, teraz wiemy nieco więcej, tutaj jest coś takiego mi chodzi:

public class Car 
{ 
    private const int DefaultGears = 5; 
    private const int DefaultTopSpeed = 180; 

    private readonly int gears; 
    private readonly int topSpeed; 

    public Car(int gears, int topSpeed) 
    { 
     this.gears = gears; 
     this.topSpeed = topSpeed; 
    } 

    public static Car CreateWithGears(int gears) 
    { 
     return new Car(gears, DefaultTopSpeed); 
    } 

    public static Car CreateWithTopSpeed(int topSpeed) 
    { 
     return new Car(topSpeed, DefaultGears); 
    } 
} 

pamiętać, że mógł użycie parametry opcjonalne i nazwane argumenty za tym też w C# 4 :

public class Car 
{ 
    public const int DefaultGears = 5; 
    public const int DefaultTopSpeed = 180; 

    private readonly int gears; 
    private readonly int topSpeed; 

    public Car(int gears = DefaultGears, int topSpeed = DefaultTopSpeed) 
    { 
     this.gears = gears; 
     this.topSpeed = topSpeed; 
    } 
} 

Następnie:

Car car = new Car(gears: 4); 
Car car = new Car(topSpeed: 30); 

Nie polecam tego jednak ogólnie - na pewno nie, dopóki jesteś stosunkowo nowy w tym języku. Istnieją różne subtelności wokół opcjonalnych parametrów.

+0

Ye, miałem na myśli liczby, moje złe. Chodzi o to, aby stworzyć domyślnego konstruktora, który sprawia, że ​​maksymalna prędkość samochodu wynosi 180 km/h i ma 5 biegów. niż potrzebuję innego przewodnika, który ma parametr, który zmienia ilość biegów i innego contructor, który zmienia maksymalną prędkość z parametrem. Z jakiegoś powodu muszę tworzyć te konstruktory i nie używać ich jako metod. – Gideon

+2

@Gideon: Wywołanie, że "zmiana" maksymalnej prędkości jest nieco mylące - to * określa * najwyższą prędkość. Nie możesz zmienić czegoś, co jeszcze nie istnieje! Mimo to wygląda na to, że odpowiednia jest reszta mojej odpowiedzi. –

+0

Gdybym użył metody statycznych metod fabrycznych. Czy zmienia się po prostu wartość liczby całkowitej po utworzeniu obiektu? Jeśli tak, to tego używam teraz. – Gideon

1

Przeciążone metody (i konstruktorzy) muszą różnić się podpisem. Oznacza to, że muszą mieć różną liczbę parametrów lub parametrów mających inny typ (lub oba typy). Nazwy parametrów nie są brane pod uwagę. Oznacza to, że nie można mieć dwóch konstruktorów, które mają jeden parametr łańcuchowy.

Konstruktory nie są przystosowane do zmiany niczego, tylko do zainicjowania obiektu. Jeśli chcesz zmienić wartość, rozważ dodanie metody takiej jak ChangeGears(string gears).

1

W skrócie nie. Konstruktory zależą nie tylko od liczby parametrów, ale również od ich typów.

public Car(string gears) 
{ 

} 

public Car(string maxSpeed) 
{ 

} 

nie można nazwać, ponieważ są one zasadniczo taki sam konstruktor, myśleć o tym, kiedy przechodzą na sznurku, jest to wartość, którą trzeba przejechać, więc kompilator nie ma pojęcia co konstruktor używać: jeśli chcesz ustawić liczbę biegów na 6 lub maksymalną prędkość na 6, to nadal będzie to new Car("6"), rodzaj niejednoznacznego nie powiedziałbyś?

Specyfikacja pracy domowej nie może zawierać dwóch konstruktorów, które pobierają ciągi znaków, ponieważ jest to niemożliwe. Naprawdę jedynym rozsądnym sposobem osiągnięcia tego byłoby użycie statycznych metod fabrycznych lub, jak powiedziałeś, wprowadzenie innego parametru.

Patrząc na to, co skomentowałeś w innych odpowiedziach, wierzę, że coś takiego może ci się przydać, jednak trudno jest dokładnie określić, czego chce Twoja praca domowa.

public Car() 
{ 
    ... // Do your setting of your default values here (# of gears, max speed) 
} 

public Car(int n) 
{ 
    if(n > 10) 
    { 
     // Use n to set your max speed 
    } else { 
     // Use n to set your # of gears 
    } 
} 

Wydaje się mało prawdopodobne, że samochód będzie posiadać więcej niż 10 biegów, albo że jego maksymalna prędkość będzie mniejsza niż 10, więc w ten sposób można korzystać z jednego konstruktora ustawiania zarówno swoich # biegów i góry prędkość. (Pamiętaj o tym, o co prosiłeś, to prawdopodobnie nie odpowie na twoją pracę domową, ale byłby to wystarczający sposób, aby użyć IMO konstruktora, który może ustawić maksymalną prędkość i liczbę biegów bez dodawania kolejnego parametru, zakładając, że masz jakiś rodzaj gwarancji, że prędkość samochodów max wynosi> = 10, a liczba biegów jest < 10)

+0

Tak, po prostu musiałbym zrobić prywatne int narzędzi = 5; jako domyślny w constuctor i utworzyć funkcję, która to zmienia? Ponieważ to właśnie mam teraz. Może to wina opisu. – Gideon

+0

@Gideon Edytowane w celu odzwierciedlenia pomysłu, należy pamiętać, że prawdopodobnie nie wystarczy odpowiedzieć na zadanie domowe. – NominSim

0
public Car(string param, bool isGear) 
{ 
    if(isGear) 
     gears = param; 
    else 
     maxSpeed = param; 
} 
+0

Myślałem o tym, ale chodzi o to, aby przekazać tylko 1 parametr, a tym samym jego 2. – Gideon

1

Każdy sposób (w tym konstruktorów) ma podpis. Sygnatura składa się z parametru Typy i ich. Nie można mieć dwóch metod, które mają tę samą nazwę i podpis.

Zakładam, że wymóg, że parametry są ciągami, jest nieporozumieniem.W takim przypadku zakładam, że liczba biegów jest zawsze liczbą całkowitą - najlepiej reprezentowaną jako liczba całkowita. Maksymalna prędkość może być wartością ułamkową - być może podwójną lub zmienną.

public class Car 
{ 
    public Car(int gears) {} 
    public Car(float maxSpeed) {} 
}