I have a base class which I want to provide some 'base' functionality for methods for all inheriting classes.
In my inheriting classes I want to do:
public override void Setup()
{
base.Setup();
}
But at the moment it says I have to use the new keyword.
How to I have it so I have to use the override keyword?
Is there any difference between how it is currently with me using the new keyword and using override?
It says so because you have not declared the base method virtual. Once you do so, the base virtual/derived override pair of keywords will make sense. Right now, the compiler is complaining that you cannot override a non-virtual method.
When you use the override keyword the derived method is used even when the instance is passed as a Base class type. Hence there needs to be a virtual in the base class so that the programme knows it has to make a runtime check of what the actual type of the instance is. It then looks up what the actual type is and if it is a derived type it checks if their is an override in the derived class for that particular method in the base class.
Member hiding is different. The base member will only be hidden if it is actually passed as an instance of the derived class. If the object is passed as a base class, the base class method will still be used. If you hide a member, you get a warning if you haven't use the new keyword. The new keyword is merely to tell the complier, that you really do mean to hide the base type method.
Related
Looking at how the as keyword works in C#, I can see that it allows for casting where explicit casting (i.e. using brackets) prevents compilation.
However In the code below I find that if I override a method in a derived class, and then safe cast as the base class, that the overridden method in the derived class still executes. Why is this? I was expecting the method as defined on the base class to execute instead.
class Base
{
public override string ToString()
{
return base.ToString();
}
public string OtherMethod()
{
return "Other method";
}
}
class Derived : Base
{
public override string ToString()
{
return "Derived class";
}
}
class Program
{
static void Main()
{
Derived d = new Derived();
Base b = new Base();
System.Console.WriteLine(b.ToString()); // Base
System.Console.WriteLine(d.ToString()); // Derived class
System.Console.WriteLine((d as Base).ToString()); // Derived class => WHY IS THIS?
System.Console.WriteLine((d as Base).OtherMethod()); // Other method
// System.Console.WriteLine((Base)d.OtherMethod()); // --- prevents compilation
// As noted in the comments, this works
System.Console.WriteLine(((Base)d).OtherMethod()); // Other method
System.Console.ReadLine();
}
}
The only time when a cast to a base-class is required and will result in the execution of a different method is when you have a case of shadowing.
Shadowing occurs when a derived class implements a method of the same name as a method in a base class1 and, explicitly, this is not an override. Usually, these are marked, instead, with the keyword new. If you have an instance of the derived class but wish to invoke the base class member, you need to cast it to that base class (or to any intermediate class in the inheritance chain that doesn't itself shadow the method in question)
In the absence of shadowing, any method invocation always uses the most derived method, based on the runtime type of the object, not the variable's declared type.
Shadowing is usually best avoided, however.
1Not necessarily the direct base class - anywhere within the chain of inheritance back to object.
This can hopefully help: https://msdn.microsoft.com/en-us/library/ms173152.aspx
Base classes may define and implement virtualmethods, and derived classes can override them, which means they provide their own definition and implementation. At run-time, when client code calls the method, the CLR looks up the run-time type of the object, and invokes that override of the virtual method. Thus in your source code you can call a method on a base class, and cause a derived class's version of the method to be executed.
In your case you're calling the Object.ToString() virtual method, and the appropriate override is selected during runtime.
That is just how inheritance and polymorphism works in C#. The as operator does a safe cast only, but internally its still a Derived. It just changes it so that the compiler knows it has the right types. With your types, the casting is unnecessary. This just works:
Base d = new Derived();
This will still call the virtual methods overridden by Derived.
As for the explicit cast, its failing because it has a lower precedence than the other operators on that expression. The whole right hand side is evaluated first, then the cast. Essentially, this is what you are telling the compiler.
string result = d.OtherMethod();
Base result2 = (Base)d;
I know we cannot create an abstract class instance, but I cannot understand why could use base invoke the constructor of the abstract class.
abstract class Fruit
{
public string Name { get; private set; }
public Fruit(string name)
{
Name = name;
}
}
class Apple : Fruit
{
public Apple(string name) : base(name) { }
}
Fruit f = new Fruit("Fruit"); // Coimple Error
Apple a = new Apple("Apple"); // Success
Dose that base keyword just invoke constructors, methods, etc?
What's the differences between create an instance and invoke a constructor?
Thanks in advance.
Only derived class (e.g. Apple) can call the constructor of its parent (abstract class) with special base word. Constructor cannot be invoked (called) directly.
I would add that the fact that an abstract class may provide a constructor doesn't mean that it's not yet abstract.
By definition, an abstract class is a class where some or none of its members don't provide a default implementation, and derived classes must provide an implementation to these members. In the other hand, since an abstract class has some of its members as just signatures - the whole abstract members -, code mustn't be able to instantiate that class.
But if a derived class - either abstract or concrete - couldn't be able to call a base abstract class constructor, abstract classes would lack polymorphic constructors and there may be no way to initialize class properties or define a default class initialization code, even if that code calls an abstract method or property.
This is why a derived class can call a parent class constructor, even if the class is abstract!
What's the differences between create an instance and invoke a
constructor?
We might try to address this question with a deep explanation with low-level details, but
I feel that it's more a conceptual issue rather than a low-level thing.
If you want a summary, calling the constructor is a part of class instantiation process. It's a method which is called once the instance has been created and initializes the instances with custom code before any other code might use that instance.
When you use base keyword in a constructor to call parent's class one, you're just chaining constructor calls from the most derived class to the base class.
Does that base keyword just invoke constructors, methods, etc?
No, use it anytime you want to explicitly invoke the parent class' methods and avoid invoking a override in the derived class. Though : base(...) syntax is exclusive to constructors, usually you would call base.method();
What are the differences between create an instance and invoke a constructor?
Creating an instance with the new operator does a number of things:
Allocates memory for the object
Initialises fields
Then finally the constructor is invoked, which will invoke base constructor first if specified.
A more in-depth explanation of the order is in this answer: https://stackoverflow.com/a/1882778/360211 but that should be enough to explain the difference.
Creating an instance with the new keyword creates a new object and returns a reference to the object.Invoking the constructor with the base keyword won't create a reference to the object(neither it will create an actual object), it will simply execute the code in the constructor.
Take a deep look onto this answer to for more information https://stackoverflow.com/a/14453366/3789232
This is a general OOP question for languages that do not support inheritance from multiple classes (not sure if that matters here, just thought I'd put that detail in), like Java:
OK, you have your base class:
class Base {}
class Derived extends Base
{
SomeMethod(){}
}
Main()
{
Base baseInstance = new Base();
Derived derivedInstance = new Derived();
baseInstance = derivedInstance;
baseInstance.someMethod(); <<<<<< this does not work. why?
}
Why, when you set the baseInstance to the derivedInstance, is it unable to call the method that is defined in the Derived class?
Since you're setting the baseInstance to be the derivedInstance, should you not have access to this method?
A variable that is typed as the base class cannot presume methods about subclasses. For example, for all the compiler knows, baseInstance could hold a reference to a Base, or to a SomeOtherClass extends Base. Now, you could say that in this case the compiler could figure it out, but: that isn't what the compiler does. The rules of the compiler are simple: if you have a variable typed as Base, you can only use things known on Base.
If you want to use specialized methods from specific sub-classes, then you'll need to ask the compiler to perform a cast with type-check, i.e.
Derived special = (Derived)baseInstance; // I'm using C# syntax here,
special.someMethod(); // but should be similar or identical
This line
baseInstance = derivedInstance;
doesn't set baseInstance to type Derived. It's still type Base.
You can only call someMethod() on an object of type Base if someMethod is a method defined in Base. The compiler does not know about more derived methods.
In java instances are created at runtime, so the actual class instance gets resolved at run-time and not during compilation.
Thus, Compiler always looks at the reference type to determine which methods or members can be referred by the referencing variable.
In your case, baseInstance = derivedInstance; even though the actual class being referred is a subclass of Base, compiler will simply assume it to be of the type Base. Obviously, Base class does not have someMethod(); hence it does not allow you to call it.
As a work around, you can try this:
if(base instanceof Derived) {
// Downcast it before calling
((Derived)baseInstance).someMethod();
}
Accidently I actually wrote this method:
public static new iTextSharp.text.Color ITextFocusColor()
{
return new iTextSharp.text.Color(234, 184, 24);
}
It is working as suspected, but I was very surprised that is it allowed to use the new keyword in the return type of the method. Is there any effect/difference if i put there new or not? Or what is the new used for?
And is this also possible in other OO-languages?
It doesn't affect the return type, it indicates that this method hides the method from the base class (rather than override it). It can be useful if you need to change the return type declared in the base class, for instance, but the hiding method won't participate in polymorphism, i.e. if you call ITextFocusColor on an instance of the derived class through a variable of the base class, the base implementation will be called (not the one declared with new)
See this page on MSDN for more details.
The new keyword specifies that you are deliberately providing a new implementation of a method or property that is already provided by a base class. It's there to make hiding of base class members a deliberate, self-documenting act.
If your base class doesn't have that method, it doesn't actually matter.
For more details, see the C# specification (specifically, section 3.7.1.2 Hiding through inheritance).
It is the new modifier. It hides members from a base class instead of overriding.
new keyword in method return type here hides the parent method.
I have a class, say DerivedBindingList<T>, which is derived from BindingList<T>.
I would like to use an indexer with the derived class, and have coded it as:
public T this[int index]
{
get
{
// Getter code
}
set
{
// Setter code
}
}
However, the compiler complains with the following message: "...hides inherited member 'System.Collections.ObjectModel.Collection.this[int]'. Use the new keyword if hiding was intended."
I can add the 'new' keyword and the compiler is happy, but should I be doing things differently in some way to avoid this warning?
Perhaps I have to use base.this[] somehow?
Thanks.
The indexer in BindingList isn't virtual, so you can't override it - you'll have to just hide it if you really want to do this.
I don't think I'd advise it though - member hiding is a recipe for confusing code. What are you trying to do? Do you definitely want to derive from BindingList<T> instead of composing it (i.e. having a member of your class of type BindingList<T>)? What is your new indexer going to do?
This warning shows that an indexer already exists in base class.If you want to change its behavior you should either override it (if it's defined as virtual in base class) or use new keyword to tell the compiler to use derived indexer method whenever it's working with an instance of derived class.