简体   繁体   中英

Error in inheritance and constructors

I'm currently studying a program wherein inheritance and constructors are involved. I'm actually a newbie in C# so I'm just wondering why does this code below has an error on line 57, it says that loan does not contain a constructor that takes 0 arguments. Please help me analyze what's wrong in it. Thank you very much. using System;

class DemoCarLoan3
{
    static void Main()
    {
        Loan aLoan = new Loan(333, "Hanson", 7000.00);
CarLoan aCarLoan = new CarLoan(444, "Carlisle", 30000.00, 2011, "BMW");
        Console.WriteLine("Loan #{0} for {1} is for Php{2}",
        aLoan.LoanNumber, aLoan.LastName,
        aLoan.LoanAmount.ToString("0,000.00"));
        Console.WriteLine("Loan #{0} for {1} is for Php{2}",
aCarLoan.LoanNumber, aCarLoan.LastName,
aCarLoan.LoanAmount.ToString("0.00"));
        Console.WriteLine(" Loan #{0} is for a {1} {2}",
        aCarLoan.LoanNumber, aCarLoan.Year,
        aCarLoan.Make);
        Console.ReadLine();
    }
}

class Loan
{
    public const double MINIMUM_LOAN = 5000;
    protected double loanAmount;
    public int LoanNumber { get; set; }
    public string LastName { get; set; }
    public double LoanAmount
    {
        set
        {
            if (value < MINIMUM_LOAN)
                loanAmount = MINIMUM_LOAN;
            else
                loanAmount = value;
        }
        get
        {
            return loanAmount;
        }
    }

    public Loan(int num, string name, double amount)
    {
        LoanNumber = num;
        LastName = name;
        LoanAmount = amount;
    }
}

class CarLoan : Loan
{
    private const int EARLIEST_YEAR = 2006;
    private const int LOWEST_INVALID_NUM = 1000;
    private int year;

    public CarLoan(int num, string name, double amount, int year, string make)
    {
        Year = year;
        Make = make;
    }

    public int Year
    {
        set
        {
            if (value < EARLIEST_YEAR)
            {
                year = value;
                loanAmount = 0;
            }
            else
                year = value;
        }
        get
        {
            return year;
        }
    }

    public string Make { get; set; }

    public new int LoanNumber
    {
        get
        {
            return base.LoanNumber;
        }
        set
        {
            if (value < LOWEST_INVALID_NUM)
                base.LoanNumber = value;
            else
                base.LoanNumber = value % LOWEST_INVALID_NUM;
        }
    }
}

When you don't declare a constructor, the C# compiler will generate a parameterless one. But when you declare a constructor that takes args, the C# compiler will not give you that default one so you have to write one.

 public Loan()
 {
 }

Just add call to the base constructor

public CarLoan(int num, string name, double amount, int year, string make) 
    : base(num, name, amount)
{
    Year = year;
    Make = make;
}

When you declare a constructor in a derived class which does not call to a base constructor, then it automatically calls a constructor with 0 parameters which does not exist there. If you take your code as is, it will compile to

public CarLoan(int num, string name, double amount, int year, string make) 
    : base()
{
    Year = year;
    Make = make;
}

But that's invalid since there is no constructor with 0 parameters in the base class. So either create one or call one of existing.

You are getting that error, because your Loan class does not contain any Default Constructor. Default Constructor means, Constructor without any arugments(parameters).

As soon as you create a Parameterized Constructor in any class, Default Constructor is destroyed, so, you cannot create instance of this class like this:

  Loan obj = new Loan();

unless you create a Default Constructor(without any arguments)

create this also in your loan class

public Loan()
{
}

All classes in c# inherit from Object class,if you don't define a parameterless constructor,your class inherit a default parameterless constructor from Object class,but if you define a constructor which takes some arguments,default constructor will be ignored.So in this case you have to define a parameterless constructor:

public Loan()
{

}

Your call to create a CarLoan object:

    CarLoan aCarLoan = new CarLoan(444, "Carlisle", 30000.00, 2011, "BMW");

invokes this constructor:

    public CarLoan(int num, string name, double amount, int year, string make)
    {
       ...
    }

What may not be obvious is that the CarLoan constructor is compiled as if you had written this:

    public CarLoan(int num, string name, double amount, int year, string make)
        : base()
    {
       ...
    }

When constructing derived objects, the base class constructor is invoked first automatically (even if you don't do it explicitly). More generically, objects are constructed in top-down fashion, from the most base class to the most derived class. Because you did not specify which Loan constructor to use, the compiler uses the parameterless constructor by default. The solution is to either provide a parameterless constructor on the Loan class:

    public Loan()
    {
    }

The other option is to use the solution suggested by @Ondrej Janacek.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM