简体   繁体   中英

Override the property of an abstract class

I want to output the numberOfLegs of my tiger1 instance. But the output is 0 instead of my expected 4. Where is my mistake? Please help the tiger to get his legs back.

using System;

namespace AbstractProperty
{
    class MainClass
    {
        static void Main(string[] args)
        {
            Tiger tiger1 = new Tiger();
            int result = tiger1.NumberOfLegs;
            Console.WriteLine(result);
            Console.Read();
        }

        public abstract class Animal
        {
            public abstract int NumberOfLegs { get; set; }
        }

        public class Tiger : Animal
        {
            private int numberOfLegs;
            public override int NumberOfLegs
            {
                get
                {
                    return numberOfLegs;
                }
                set
                {
                    numberOfLegs = 4;
                }

            }
        }
    }
}

EDIT: I think it is not good to use numberOfLegs = 4 in a Setter

The NumberOfLegs property setter is not called as you're not changing the value anywhere in your code. The int value is zero by default. You can do one of the following:

  1. Define the default value of numberOfLegs variable when declaring it:

private int numberOfLegs = 4;

  1. Define the numberOfLegs value in constructor of Tiger class:
 public class Tiger : Animal { private int numberOfLegs; public Tiger() { numberOfLegs = 4; } // ... } 

You are doing it all wrong...

Don't provide a setter for numberOfLegs . Just provide a getter. And then set the number of legs in the constructor, or just set the field directly, like so:

public abstract class Animal
{
    public abstract int NumberOfLegs { get; }
}

public class Tiger : Animal
{
    private int numberOfLegs = 4;
    public override int NumberOfLegs
    {
        get
        {
            return numberOfLegs;
        }
    }
}

The reason your code wasn't working was because you weren't calling the setter for Tiger.NumberOfLegs , but of course if you did so you'd realise how wrong it was:

Tiger tiger1 = new Tiger();
tiger1.NumberOfLegs = 100;
int result = tiger1.NumberOfLegs; // Set to 100, but now it's 4! Urk.

As I see, the set accessor for NumberOfLegs is never called, thus numberOfLegs has the default value 0.
You could write a constructor and assign some value to NumberOfLegs , which would be assigned 4 anyway as you have hard-coded 4 in the set accessor, ie if you write your constructor like this:

public Tiger() {
  NumberOfLegs = 10;
}

The set accessor would be called and assign 4 (not 10 ) to numberOfLegs . Perhaps you have mixed up the concepts a bit here :)

EDIT 1: If you now understand that assigning a hard-coded value in the setter was not that great, and you don't want to do anything special in the setter, it would be better to use the traditional approach for properties:

private int numberOfLegs;
public override int NumberOfLegs
{
    get
    {
        return numberOfLegs;
    }
    set
    {
        numberOfLegs = value;
    }
}

Or simply

public override int NumberOfLegs { get; set; }

which does the same thing as above.
And assign value to NumberOfLegs in the constructor:

public Tiger() 
{
  NumberOfLegs = 4;
}

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