2

Let's see the example at first:

using System;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            Person p = new Manager();
            Manager p2=new Manager();

            p.Name = "Ahmad";
            p.Introduce();
            p.SayHello();
            p2.SayHello();
            p2 = (Manager)p;
            p2.SayHello();
        }
    }

    public abstract class Person
    {
        protected Person()
        {
            Name = "Reza";
            Introduce();
        }

        public abstract string Name { get; set; }

        public void SayHello()
        {
            Name = "Ali";
            MessageBox.Show(Name);
        }
        public abstract void Introduce();
    }

    public class Manager : Person
    {
        public new void SayHello()
        {
            MessageBox.Show("Test2");
        }

        public override string Name { get; set; }

        public override void Introduce()
        {
            MessageBox.Show("Hello " + Name);
        }
    }
}

at first i hadn't written constructor for base class.

as far as i know the purpose of abstract method is to force the derived class to implement from it, and because of that we can't implement abstract methods in base class.

then i added an abstract property. and i saw that we can initialize that property in base class and using it.

1st: Wasn't the purpose of abstract to just declare them and let derived class to implement it?
Why can we use the property in base class?

we could just implement a non-abstract property at first, and it would make no difference.

then i added the constructor and things get more complicated. we can use Introduce() method in constructor to call Introduce() from Child class (i understand that from debugger).

so Child inherits from Father here, but we call a method in Child from Father, which is strange and is somehow against the rules of inheritance.

2nd: What have i missed?

Edit:

enter image description here

enter image description here

Yuval Itzchakov
  • 146,575
  • 32
  • 257
  • 321
Masoud Mohammadi
  • 1,721
  • 1
  • 23
  • 41

1 Answers1

2

Wasn't the purpose of abstract to just declare them and let derived class to implement it? Why can we use the property in base class?

You can't use the abstract property in the base class, as you cannot instantiate it directly. You'd create an abstract property for the same reasons you'd want to create an abstract method, which is make sure your derived types implement it.

Your Name property isn't actually using the base-class instance. When called from SayHello, it will go to your derived-type implementation of Name and use that.

So Child inherits from Father here, but we call a method in Child from Father, which is strange and is somehow against the rules of inheritance. What have i missed?

It's not only strange, its an error which might cause a run-time exception, for the fact that the child object hasn't been initialized yet. If you were to access any member of Manager that are instantiated via managers constructor (not via field initialization) inside Introduce, you would get an exception:

public class Manager : Person
{
    public Manager()
    {
        s = "Hello";
    }

    private string s;

    public override string Name { get; set; }

    public override void Introduce()
    {
        Console.WriteLine(s.ToLower());
    }
}

When you now call Introduce, you'll see a NullReferenceException, as s hasn't been initialized yet.

If you want to call an abstract method on derived type, make sure you do it after object instantiation. Perhaps via an Initialize method on the base.

You can read Virtual member call in a constructor for more information:

if you make a virtual method call in a constructor, and it is not the most derived type in its inheritance hierarchy, that it will be called on a class whose constructor has not been run, and therefore may not be in a suitable state to have that method called.

Community
  • 1
  • 1
Yuval Itzchakov
  • 146,575
  • 32
  • 257
  • 321
  • 1
    I used the abstract property in base class, I Instantiate Name property in SayHello method and used it. and about the second answer, i didn't get any compile error. – Masoud Mohammadi Feb 05 '15 at 12:36
  • i didn't get a runtime exeption, have you noticed Person p = new Manager(); in the first line. – Masoud Mohammadi Feb 05 '15 at 12:38
  • i still don't get any run-time exception, not even in debug mode. on which line you get the error. make sure you have typed everything as same as mine. – Masoud Mohammadi Feb 05 '15 at 12:46
  • Yes you don't necessarily get a run time exception. It dependson the order that the constructors are called. It is certainly bad practice – Tim Rutter Feb 05 '15 at 12:46
  • @afrogonabike That's correct, i edited my answer to reflect that. – Yuval Itzchakov Feb 05 '15 at 12:47
  • @YuvalItzchakov I have GetBrain Resharper installed in my PC. and about Name = "Reza"; and Introduce(); in constructor it gives warning with message Virtual member call in constructor. and suggestion for Name property to fix is: public abstract string Name { get; set; } = "Reza"; which is a C# 6 Feature and there is a compile error because i use C#5, but if that can be happened we have initialized Name directly which is using abstract property in same class. and anyway resharper don't get warning for Name = "Ali"; in SayHello() which is again strange. – Masoud Mohammadi Feb 05 '15 at 13:03
  • You can't assign a value directly to an `abstract` member, [this won't work in C# 6.0 either](http://tryroslyn.azurewebsites.net/#b:master/K4Zwlgdg5gBAygTxAFwKYFsDcAoADsAIwBswBjGAQwJQCcLTkZSiKQQYBhGbAb2xgEx8xMpWrI6DGLUiwAchXSoYPGFFTJM0jVoC+MALwwARAAtURIgHtjOXUAA=). About the second question, of course it doesn't give you an error, because "SayHello" will refer to the derived types property, not the base classes. – Yuval Itzchakov Feb 05 '15 at 13:06
  • @YuvalItzchakov resharper mistake.finally the problem solved. thanx for your excellent support. – Masoud Mohammadi Feb 05 '15 at 13:21