Why are some classes derived from an interface instead of the actual class?
For example, TSList is derived from IList instead of List...
I think of interfaces as exactly what the word Interface means.
Say you have your class: public class House : Foundations, IDestructable
The House class inherits all the functionality of the Foundations class.
It also states that this house class will definitely contain methods describing something IDestructable. Therefore you can Interface from a different method an IDestructable instead of specifically the House.
so instead of
void Destroy(House object) { object.Explode(); } void Destroy(PlantPot object) { object.Explode(); } // etc...
You can have this which takes an argument for an object that implements an IDestructable interface rather than having many "Destroy" functions to complete the same task for every item.
void Destroy(IDestructable object) { object.Explode() }
I understand the idea of interfaces, it just confused me when I saw TSList implementing IList rather than being derived directly from List. I'm certain I would have derived from List and just overridden (hidden) the old Add / Remove methods, rather than having to implement all of IList's methods. I'm trying to understand why this is wrong... I have no doubt this IS wrong, just trying to get a good understanding of why.
Thanks for the quick reply btw. =P
edit: I posted this before I read aphros post on interfaces. I was missing half of the benefits of interfaces, I didnt realize you could indirectly access the object through the interface like that.
TSList can't derive from List, though, since List's methods aren't virtual. So the best it can do is derive from IList, and use a List internally, which it does. ![]()
class MyList<T> : List<T> { readonly object _threadSync = new object(); public new void Add(T item) { lock (_threadSync) base.Add(item); } public new void Remove(T item) { lock (_threadSync) base.Remove(item); } }
Does MyList not derive from List? Or is there some other fancy OOP term for whats going on here?
That does not work... overriding a method and using new are two TOTALLY different things. Its recommended that you never even use "new" in method declarations unless you have to just because it can be misleading and confusing.
using System; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { Console.WriteLine("1a. " + new DerivedNoNew().A()); Console.WriteLine("1b. " + new DerivedNew().A()); Console.WriteLine("2a. " + (new DerivedNoNew()).A()); Console.WriteLine("2b. " + ((BaseClass)new DerivedNew()).A()); Console.ReadLine(); } } class BaseClass { public virtual string A() { return "A"; } } class DerivedNoNew : BaseClass { public override string A() { return "Overridden A"; } } class DerivedNew : BaseClass { public new string A() { return "New A"; } } }
Run this code, and pay special attention to the output of 2b. Notice returns "A", not "New A". This is because its not overridden. Thus, casting to any less-derived classes or interfaces makes you lose the new method implementation. Its not polymorphism like the other where you are overriding the method.
Ahh, I see now. I assumed it had to be wrong, but just wasn't sure 'how' since it appeared to work properly. This sort of thing tricks me because I might not notice the odd behavior until later.
Thanks for taking the time to clear this up. =P
No sweat. ![]()
It's kinda different although you do know how to use them. This is why I like the obj-C terms much better. In obj-C you have @protocol, @interface, @implementation, an interface is basically the header/prototype for @implementation, while @protocol joins together a family of like functionality.
Basically an interface is more like a protocol, where implementations of like functionality must contain the same interface for flexibility. (or maybe this is just my opinion)
Implementation inheritance means
1. You are locked into specific implementations
2. You must know a lot more about the derived implementations
This means that any changes made higher up must be accounted for lower down, making the program a lot more fragile. Single implementation inheritance solves this a little, although if you look at Java's libraries you would know why this is still bad. Interface inheritance doesn't have these problems.
The House class inherits all the functionality of the Foundations class.
This is why knowing definitions matters so much. Inheriting functionality is not a good way to think about implementation inheritance. Implementation inheritance should be viewed as a way of generalising and specialising things. Therefore you get base classes which provide a framework for creating specialised classes. Functionality is always changing, if your base classes have to change all the time you will end up with chaos.
Inheritance hierarchies should not span too long either, as this would cause the program to become fragile. Thus a good program may consist of a few inheritable abstract base classes and a series of specialised classes. New programmers should be able to just look at the abstract base classes and be able to work out most of the functionality of all its child classes. The functionality of the base classes should be simple and unchanging. Therefore programmers should be forward thinking when designing these base classes, and implement it in a way which would require minimal modification in the future.
Let's say we want to design a set of GUI Components, in order to make our lives easier we could create a Component abstract base class.
public abstract class Component { private float x, y, width, height; private boolean visible; public Component () {} public Component (float x, float y, float width, float height) { setX(x); setY(y); setWidth(width); setHeight(height); } public abstract void draw(); public void setPosition (float x, float y) { setX(x); setY(y); } public void setSize (float width, float height) { setWidth(width); setHeight(height); } public float getHeight () { return height; } public void setHeight (float height) { this.height = height; } public float getWidth () { return width; } public void setWidth (float width) { this.width = width; } public float getX () { return x; } public void setX (float x) { this.x = x; } public float getY () { return y; } public void setY (float y) { this.y = y; } public boolean isVisible () { return visible; } public void setVisible (boolean visible) { this.visible = visible; } }
Yeah i understand what you are saying. Damn i wish i'd worked harder in school and could go university ![]()
Base classes provide implementations, while interfaces do not. Therefore, interfaces are all about what something can do, not at all about how it does it. Take IEnumerable for instance. It is used on arrays, lists, linked lists, XML nodes, file lines, database reading, etc. These all implement it differently, but IEnumerable still does the same in all cases.