7

So, at school we got an assignment to make a car in OOP, until now its been pretty easy and straight forward. But now I need to create four constructors, one with no parameters, two with one parameter and one with two parameters.

As far as I know the way overloading works is that it checks the amount of parameters you supply it with and then checks which constuctor it has to use. As two of the constructors are the same, both accepts ints, only one needs to change the amount or gears, and the other needs to change the maximum speed.

Is there a way to do this without passing an extra parameter?

5
  • I think you misread the assignment: why would you pass in the amount of gears (a number) or the maximum speed (also a number) as a string? But this observation doesn’t necessarily solve the problem. Your doubt is essentially correct – it’s questionable whether a good OOP design would use constructors here. Commented Mar 2, 2012 at 21:57
  • Is your assignment to use constructors, or is that your way of solving the particular assignment? Commented Mar 2, 2012 at 21:58
  • Sounds like that would cause ambiguity. Not sure this is even possible. Commented Mar 2, 2012 at 21:58
  • Ooops, meant int, sorry. I have no idea why, maybe because it's possible and we need to learn how? AnthonyPegram, Its the assignment to make them. :) MikeWebb That's what I was thinking Commented Mar 2, 2012 at 21:59
  • google c# method signatures, that will give you a start understanding method overloading. Commented Mar 2, 2012 at 21:59

5 Answers 5

16

As far as I know the way overloading works is that it checks the amount of parameters you supply it with and then checks which constuctor it has to use.

No, overloading isn't based solely on the number of parameters - it's based on their types too.

However:

As two of the constructors are the same, both accepts strings

That's a problem. You can't declare two constructors like this:

public Foo(string x)
{
}

public Foo(string y)
{
}

Those signatures clash as far as overloading is concerned.

I would suggest having public static factory methods, so you can specify what you're trying to create:

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

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

You'd then possibly have one constructor which accepted both values, and default whichever one's missing when you call the constructor from the factory method.

However, there are two other oddities in your description:

  • You're using strings for two values which sound like they should be numbers (or possibly one number, and one number-and-unit)
  • You're talking about declaring constructors, but then using the word "change" as if they're going to change an existing instance. That doesn't make sense - constructors are used to create new objects.

EDIT: Okay, now we know a bit more, here's the sort of thing I mean:

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);
    }
}

Note that you could use optional parameters and named arguments for this too in 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;
    }
}

Then:

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

I wouldn't recommend that in general though - certainly not while you're still relatively new to the language. There are various subtleties around optional parameters.

Sign up to request clarification or add additional context in comments.

8 Comments

Ye, I meant numbers, my bad. The idea is to make a default constructor that makes the car's top speed 180 km/h and have 5 gears. than I need another constuctor that has a parameter that changes the gears amount and another contructor that changes the top speed with a parameter. For some reason I need to make these constructors, and not use them as methods.
@Gideon: Calling that "changing" the top speed is a bit confusing - it's specifying the top speed. You can't change something that doesn't exist yet! Still, it sounds like the rest of my answer is appropriate.
If I would use the static factory methods method. Is this just changing the amount of an integer after the object has been created? If so, thats what I use now.
@Gideon: No, the static method would call the constructor taking both values. Will edit with an example.
The first example looks perfect, but how do I create the object in my program? because I don't realy know what "Car CreateCarWithGears" does, is it like a sub-constructor? Normally you would do Car audi = new Car(5), but how do the CreateWith things work? Thanks for the awsome help so far :)
|
1

Overloaded methods (and constructors) must differ in their signature. This means that they must have a different number of parameters or parameters having a different type (or both). The names of the parameters are not taken into account. This means that you cannot have two constructors both having one string parameter.

Constructors are not made to change anything but to initialize an object. If you want to change a value, consider adding a method like ChangeGears(string gears).

Comments

1

In short no. Constructors not only depend on the number of parameters but on their types as well.

public Car(string gears)
{

}

public Car(string maxSpeed)
{

}

You can't call that, because they are essentially the same constructor, think about it, when you pass in a string, it is a value that you are passing, so the compiler has no idea what constructor to use: if you wanted to set number of gears to 6 or max speed to 6 the call would still be new Car("6"), kind of ambiguous wouldn't you say?

The homework spec can't say to have two constructors which take strings, since this is impossible. Really the only sane way to accomplish this would be to use static factory methods or as you said to introduce another parameter.

Looking at what you have commented on in other answers leads me to believe something like this might work for you, however it is hard to know exactly what your homework wants.

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
    }
}

It seems unlikely that a car will possess more than 10 gears, or that its maximum speed will be less than 10, so in this way you can use a single constructor for setting both your # of gears and top speed. (Keep in mind from what you've asked that this probably won't answer your homework, but it would be a sufficient way IMO to use a constructor that can set max speed and number of gears without adding another parameter, assuming that you have some sort of guarantee that the cars max speed is >=10 and the number of gears is < 10)

2 Comments

So, I would just have to make a private int gears = 5; as default in the constuctor, and make a function that changes that? Because that is what I have now. Maybe it's a fault in the description..
@Gideon Edited to reflect an idea, keep in mind that it probably isn't sufficient to answer your homework.
1

Every method (including constructors) has a signature. The signature is comprised of the parameter Types and their order. You cannot have two methods that share the same name and signature.

I'm assuming that the requirement that the parameters be strings is a misunderstanding. In which case I'd assume that the number of gears is always a whole number - best represented as an integer. And the max speed might be a fractional value - possibly a double or float.

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

Comments

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

1 Comment

Was thinking this, but the idea is to only pass 1 parameter, and this way, its 2.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.