views:

290

answers:

7

Hi,

I was thinking a scenario like that :

class Utopia => A Base Class which pass it's fields and methods to derived classes.

class Watashi => A derived class, derived from Utopia and inherits everything

class Baka => A derived Class, Inherits some fields from Utopia

There are some types above and Type Baka should inherit some specific fields and methods but how ? How can I specify fields and methods that only Baka will inherits whereas Watashi inherits everything from Utopia.

Sample Code :

class Utopia {
   public string Moshi;

   [Exclude(ClassName("Baka"))]
   public string HaveIt;
}

class Baka : Utopia 
{
 // only Moshi appears here
 base.[Moshi]
}

class Watashi : Utopia 
{
  base.[Moshi][HaveIt];
}

If I want to use Polymorphism :

   Utopia _utopiaBaka = new Baka();
   _utop.[Moshi];

   Utopia _utopiaWatashi = new Watashi();
   _utopiaWatashi.[Moshi][HaveIt];

And of course Framework also checks the derived class whether they are base classes for other types.

+7  A: 

Split Utopia into more than one class. Have one class that any class can inherit from, so Baka would inherit from that.

Then, extend this PartialUtopia class, add the rest of the methods and have Watashi inherit from that.

This way you can have a way to have classes pick which methods they need by which base class they extend.

James Black
I am just thinking if we can use Attributes to achieve that ?
Braveyard
not possible, attributes can't change the compile time visibility of methods/properties. You could look at them with reflection and determine if that method would be allowed to be called or if it should be denied because it carries a certain attribute
Tom Frey
If you were doing this in java then aspectj would enable you to do what you want by using interfaces, and injecting the code into the interfaces, but, that is java, I haven't seen anything in C# that can do what AspectJ does.
James Black
Classic OO here. +1
Cameron MacFarland
@James: There's a few AOP for C# out there. PostSharp and Aspect# spring to mind.
Cameron MacFarland
@Cameron MacFarland - PostSharp doesn't have the same power as AspectJ 6, and Aspect# doesn't seem to be maintained anymore. C# and Java have diverged and Java seems to have taken AOP to heart more.
James Black
Then how would I do that with Java ? At least I would learn the logic behind it, Thanks.
Braveyard
@Aaron - In Java I can have a base class that has limited functionality, but everything inherits from. I also have interfaces, so Watashi inherits two interfaces, Baka inherits just one of the interfaces. I then inject my methods and properties into the two interfaces, so, anything that inherits the interface will get the appropriate methods.
James Black
@James, I think it could be accomplished with C# ? I mean what's the problem with that that c# can't handle ? Thanks for the answer.
Braveyard
@Aaron - in C# you can't put code into interfaces, just definitions for functions.
James Black
@James, I didn't know java interface accepts codes :) Thanks tho.
Braveyard
@Aaron - Java doesn't accept code in interfaces, but using AspectJ I can inject code into interfaces. It allows me to get around some of the limits of Java, and is a tangential style of programming to OOP.
James Black
@James, thanks for clarifying that :)
Braveyard
+1  A: 

Thats not how inheritance works in OOP. Baka inherits everything from Utopia just like Watashi.

Asaph
I know but why not ? Maybe there is an attribute or something which I can specify which types will be excluded during inheritance.
Braveyard
@Aaron: Doing so would break polymorphism. When a Baka is cast as a Utopia type, all the methods of Utopia need to be available.
Asaph
Because you would not have polymorphism which is a main goal or inheritance.
Aaron Fischer
Well, actually it also should prevent it from happening. When I cast Baka as Utopia Type, then the only methods,fields that Baka can inherit should be appeared.
Braveyard
@Aaron: If you did that, your Baka cast as a Utopia would effectively be a broken instance of a Utopia because some of the methods wouldn't work.
Asaph
@Asaph, Would it be bad ? I mean it's programming language so I think it would be able to handle it :)
Braveyard
@Aaron: I guess "bad" is a matter of opinion here. It wouldn't be polymorphism though because it breaks the contract that all derived classes can act as fully functional stand-ins for their parent classes.
Asaph
@Asaph : Then we would redefine the meaning of Polymorphism :) I mean you think that because the definition of Polymorphism but they said Java supported that kind of thing.
Braveyard
+1  A: 

This is not how inheritance works, you would have to split up your classes. If you and your girlfriend get a child, you can't chose that it only inherits genes for blue eyes and a musculus body :)

Tom Frey
Well, this is a computer world right ? :)
Braveyard
+1  A: 

I would suggest researching the differences between public, private, and protected. It sounds like that whats your looking for.

http://msdn.microsoft.com/en-us/library/ms173149.aspx

Joey Tiell
Well actually none of those keywords works for this situation. They don't filter them, just hide or allow.
Braveyard
Ah right. Good point.
Joey Tiell
+1  A: 

What you want to do is completely incompatible with the concept of inheritance in Object Oriented programming. It is like asking "Why is blue blue?" if blue was not blue it would not be blue.

When one class (Baka) inherits from another (Utopia) this means (in OOP) that Baka can do everything that Utopia can - OOP languages offer features that rely upon this and if you were able to override you would cause horrible exceptions.

For example, if I have a method that takes a class of type Utopia as a paramter as below:

public void TakesUtopia(Utopia utopia)
{
    utopia.BePerfect();
}

We can also pass in classes of type Watashi and type Baka because they both inherit from Utopia. Baka, by inheriting from Utopia is guaranteed to have an implementation of the method BePerfect()

If somehow an instance of Baka did not have an implementation something horrible would happen.

To further this - consider what happens when TakesUtopia relies upon the behaviour of Utopia. Say for example utopia exposes a PriceOfHappiness property.

public string TakesUtopia(Utopia utopia)
{
     if (utopia.PriceOfHappiness() > 100)
     {
          return "Can't buy happiness';
     }
}

When writing my TakesUtopia method, should I be expected to write code to deal with the possiblity that any method within utopia is not implemented? What would such methods do when they are called?

David Hall
Well, The thing that I can't understand why it would be against OOP logic. For example, it is something like a genetic engineer flags some genes to avoid them to be inherited to specific kids. It wouldn't go against the OOP nature ?
Braveyard
And I don't believe it will ruin OOP logic too.
Braveyard
How can my class that takes objects of type utopia function if it is able to receive objects that don't implement the members of utopia? What should I as a developer do in this world? Should I be expected to write code that deals with the case where someone decided to not inherit fully from a base class, for every single call I make to members of that base class? It would be entirely unworkable.
David Hall
What if I don't want to write the same codes that base type already have and don't want to see inherited fields in my derived type ?
Braveyard
You don't need to write the same code - if you inherit from a base class you are only forced to write your own implementation of a member if that member is declared abstract.
David Hall
Could you give me a sample code which achieve the same thing that I mentioned about ? Thanks.
Braveyard
Aaron, you are lacking a fundamental understanding of the Liskov Substitution Principle. http://en.wikipedia.org/wiki/Liskov_substitution_principle . Inheritance in OOP is not like genetic inheritence, it's more like cloning with adding additional things. If B inherits from A, then B *IS AN* A and B has all the functions, properties, and traits of A. This is why you can assign a B to an A reference and nothing goes wrong, because B is a complete superset of A. It is not (as in genetic inheritence) part A and part A2.
Mystere Man
Thanks for the recommendation but so if this OOP is not the same thing that we get from genetics, then why the thing I said above would go against the nature of OOP ? Actually I knew it wasn't the same thing as in the real life so that's why I said that :)
Braveyard
My answer explains why this is not in the nature of OOP, as do several of the other posts - OOP polymorphism relies upon the fact that things which inherit form a class can function as though they were of that class. That's just how OOP is.
David Hall
Then we are stuck in the definition of OOP ? Alright then, what if they change the definition of it, then you'd say it was acceptable ?
Braveyard
They're not going to change the definition, it would break too many things. They may come up with a totally new form of programming with a different, but related paradigm, but OOP is what it is today and will not change.
Mystere Man
Sure - if you define a language where you do not gain object polymorphism through inheritance, then yes, you can do what you want.IMO that would be a quite useless and frustrating language to try and code in.
David Hall
Alright alright, it seems it's not going any where. I was just asking whether there was a something like that or not and not :)
Braveyard
And +1 for the conversation.
Braveyard
+1  A: 

What are you trying to do specifically? If you are concerned about a subclass overriding a given method implementation, you can always declare a method sealed:

class FooBase
{
    sealed void Bar()
    {
        //base implementation
    }
}

class FooDerived
{
    void Bar()  //poof! compilation error
    {
        //never reached
    }
}

Alternatively, you can have your inheriting subclass inside the assembly and the non-inherting outside. Just use protected internal.

byte
But what about the other types that want to inherit Bar() ?
Braveyard
@Aaron, I think you misunderstand... Bar() is still inherited in this situation. This just prevents the subclass from reimplementing it.
byte
@Dxmio : so ? I mean it isn't what I wanted then :) I mean I don't want to re-implement or something, I basically don't want to see things that I don't want to be inherited.
Braveyard
@Aaron Then I direct you to the other answers. What you want does not follow the OOP model. You would need to rethink your architecture.
byte
+1  A: 

There's two different concepts: interfaces and inheritance. Basically they're two different questions. One is "How do I want to interact with this object?" (interface). The second is "How does this object work internally?" (inheritance).

In classic OOP examples, consider a base class:

class Shape {
 virtual void draw();
 virtual int size();
}

This is an interface, it defines how you work with different shapes. Now consider these:

class Square : Shape {
 ...
}

class Circle : Shape {
 ...
}

While the interfaces to these two classes would be the same (draw() and size()), the implementations would not share anything in common. Is the drawing code for a circle really relevant at all to the drawing code for a Square? No, they just share the same name & desired result.

The reason I bring this up is because if you want some classes to inherit some members of other classes, then you may have the problem that you're confusing inheritance with interfaces. AFAIK, C++ doesn't support interfaces (I'm probably wrong about this). But you could fake this with 'pure virtual' classes (like the Shape above).

class Shape {
 virtual void draw();
}

class EdgyShape : Shape {
 virtual int width();
 virtual int height();
}

class RoundyShape : Shape {
 virtual int radius();
}

Now you have interfaces with a heirarchy, but no implementation at all.

class Circle : RoundyShape {
 ...
}

class Rectangle : EdgyShape {
 ...
}

class Square : Rectangle {
 ...
}

So Circle and Rectangle share no code with each other, while Rectangle and Square do. And all 3 share the same basic Shape interface, with some additions depending on the type.

Maybe this sheds light on how to refactor your class heirarchy so you can split them up better?

Rocketmonkeys