1

So I only want to use one class Object for all of my functions but I do not want to directly use that class instead I need to access the members of the derived classes.

Take this example:

class A {
    public A() {

    }

    public void DoSomething() { }
}

class B : A {
    public B() {

    }

    public void DoSomethingBetter() { }
}

class C : A {
    public C() {

    }

    public void DoSomethingBest() { }
}

class Runner {
    public static void Main(String[] args) {
        A objB = new B();
        objB.DoSomethingBetter(); //Won't compile

        A objC = new C();
        objC.DoSomethingBest(); //Won't compile
    }
}

I don't want to initialize them as B objB = new B(), that is not the purpose and I already know that that could be a solution. I need to just use the parent class for this.

Thanks

2
  • 4
    Please explain the reasoning for this requirement. Commented Nov 20, 2012 at 20:24
  • 2
    Are you sure you don't want to just override DoSomething instead? Commented Nov 20, 2012 at 20:27

4 Answers 4

3

If you're going to declare the methods with different names, you're going to have to instantiate the explicit type in your code.

If the methods all perform the same function but in different manners, you should override the method from the base class rather than re-implement it with a different name.

public class A
{
    public virtual void DoSomething()
    {
         // some implementation
    }
}

public class B : A
{
    public override void DoSomething()
    {
        // body of DoSomethingBetter
    }
}

public class C : A
{
    public override void DoSomething()
    {
        // body of DomSomethingBest
    }
}

The body of your application would simplify to:

A b = new B();
A c = new C();

b.DoSomething() // uses logic of DoSomethingBetter
c.DoSomething() // uses logic of DoSomethingBest
Sign up to request clarification or add additional context in comments.

Comments

1

Not 100% sure what you're trying to accomplish, but this is an option if for some reason you don't want to override as others suggested.

class A {
    public A() {

    }

    public void DoSomething() { }
}

class B : A {
    public B() {

    }

    public void DoSomethingBetter() { }
}

class C : A {
    public C() {

    }

    public void DoSomethingBest() { }
}

class Runner {
    public static void Main(String[] args) {
        A objB = new B();
        if (objB is B)
            ((B)objB).DoSomethingBetter();

        A objC = new C();
        if (objC is C) 
            ((C)objC).DoSomethingBest();
    }
}

EDIT: A more efficient way to do this is as follows (it will run 2 casts instead of 4):

class A {
    public A() {

    }

    public void DoSomething() { }
}

class B : A {
    public B() {

    }

    public void DoSomethingBetter() { }
}

class C : A {
    public C() {

    }

    public void DoSomethingBest() { }
}

class Runner {
    public static void Main(String[] args) {
        A objB = new B();
        B objAB = objB as B;
        if (objAB != null)
            objAB.DoSomethingBetter();

        A objC = new C();
        C objAC = objC AS C;
        if (objAC != null) 
            objAC.DoSomethingBest();
    }
}

4 Comments

Ah this is what I am looking for, I originally tried on my own (B)objB.DoSomethingBetter() but it did not work but now I see why I need the other parenthesis. Thanks
This is a bad design to do it this way despite that this works. It breaks the whole reason for having B and C derive from A in the first place.
It might be bad design, but that is what my program requires
@sl133 - Assuming DoSomethingBetter and DoSomethingBest achieve the same end result as DoSomething but using a different algorithm, then there are obviously other better designs to meet your program's requirements.
1

Is it perhaps overriding that you are looking for?

You can make the A class abstract, and methods in it also. Then put the actual implementation in the derived classes:

abstract class A {

    public A() {
    }

    public abstract void DoSomething() { }
}

class B : A {

    public B() {
    }

    public override void DoSomething() { }
}

class C : A {

    public C() {
    }

    public override void DoSomething() { }
}

class Runner {
    public static void Main(String[] args) {
        A objB = new B();
        objB.DoSomething(); // Uses the B implementation

        A objC = new C();
        objC.DoSomething(); // Uses the C implementation
    }
}

3 Comments

Not quite, because if I still have different methods or even variables inside either B or C, I would have to declare them in A first which I don't want to do. I could declare all the variables inside A but I feel like there is a better way to accomplish that without overriding everything from A.
@sl133: That's the only way to access anything though an A reference. If you don't want to use a specific reference (or cast the reference), then the A class has to know about everything that you want to do.
I forgot about casting the reference, but that is what I was looking for
0

Without seeing your actual code I'm inclined to agree with everyone else who says you should really try again to fix your problem using simple overrides.

Nevertheless, I had some fun toying around with this problem and managed to write a solution that does no casting.

Enjoy!

public class BattlePlan
{
    public Action<Puppy> ExecutePuppyAttack { get; set; }
    public Action<Pigeon> ExecutePigeonAttack { get; set; }
}

public abstract class Animal
{
    public abstract void Attack(BattlePlan battlePlan);
}

public class Puppy : Animal
{
    public void Bite(bool barkFirst)
    {
        // optionally bark at the intruder,
        // then bite as deeply as needed.
    }

    public override void Attack(BattlePlan battlePlan)
    {
        battlePlan.ExecutePuppyAttack(this);
    }
}

public class Pigeon : Animal
{
    public void Bombard(int altitude)
    {
        // ewww. nuff said.
    }

    public override void Attack(BattlePlan battlePlan)
    {
        battlePlan.ExecutePigeonAttack(this);
    }
}


public class EvilMasterMind
{
    private bool _puppiesMustBark = true;
    private int _pigeonAltitude = 100;

    public void Attack()
    {
        var battlePlan = new BattlePlan
        {
            ExecutePuppyAttack = e => e.Bite(_puppiesMustBark),
            ExecutePigeonAttack = e => e.Bombard(_pigeonAltitude)
        };

        var animals = new List<Animal>
        {
            new Puppy(),
            new Pigeon()
        };

        foreach (var animal in animals)
        {
            animal.Attack(battlePlan);
        }

    }
}

Comments

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.