I have a base class (A), below, that I always want to inherited from
class A
{
abstract protected int foo();
public int foo2()
{
//do some stuff
foo();
}
}
This will not work because I can't have an abstract method in non-abstract class. But how can I accomplish the follow goals:
classes that inherit class A will have foo2 already implemented but classes that inherit MUST implement foo? It would also be preferable that foo2 is overridable.
Update: Class A did NOT have to be non-abstract
Just make the class A abstract. Abstract classes can have some methods implemented.
Make foo2() virtual, then classes derived from A can override it.
I expect that you have a valid reason to not make A abstract. The prefered way to change the behaviour of an existing non abstract class is to inject that behaviour.
interface IFoo
{
int Foo();
}
class A
{
private IFoo foo;
public A(IFoo foo)
{
this.foo = foo;
}
public int Foo2()
{
//...
return foo.Foo();
}
}
you will receive errors when you build the project
you can't define abstract method in non-abstract class
Exception
Error 1 ' .A.foo()' is abstract but it is contained in non-abstract class
Related
I have an interface and an abstract class inheriting this interface.
public interface ISomeInterface
{
int Method()
{
return 1;
}
}
public abstract class SomeAbstractClass : ISomeInterface {}
Now I want to implement a class inhereting SomeAbstractClass that will also implement int Method().
public class SomeClass : SomeAbstractClass
{
public int Method()
{
return 2;
}
}
However when calling Method() on a casted SomeClass object to ISomeInterface it'll display 1.
ISomeInterface someClass = new SomeClass();
Console.WriteLine($"{someClass.Method()}"); // displays 1
But if I add interface to SomeClass
public class SomeClass : SomeAbstractClass, ISomeInterface
{
public int Method()
{
return 2;
}
}
It'll display 2.
Why is that the case? Is there any way to declare/implement Method() by just inhereting from SomeAbstractClass but without the need to write , ISomeInterface too?
I also don't want to modify the SomeAbstractClass if possible.
I tried searching for the explanation online, but it's difficult to explain this problem in a simple sentence. I've tried to read more about default interface methods, but learned nothing meaningful.
As you have noticed, the Method declared in SomeClass does not implement ISomeInterface.Method. You cannot implement ISomeInterface.Method in SomeClass, because SomeAbstractClass has already fully implemented ISomeInterface.
By not declaring any members matching the signature of ISomeInterface.Method, SomeAbstractClass fully implements ISomeInterface by "opting in" for the default implementation of Method.
This is consistent with how abstract classes usually work - if Method didn't have a default implementation, an empty SomeAbstractClass would have caused a compiler error. If you want SomeAbstractClass to not implement Method, and let its concrete subclasses do the job instead, you need to add the following to SomeAbstractClass (regardless of whether Method has a default implementation):
public abstract int Method();
When Method does have a default implementation, this is called reabstraction.
See also this question, which is about how you still have to declare the member in the abstract class, in order for it to implement a non-default interface member.
Note that by adding the abstract method to SomeAbstractClass, you would now also be able to call Method on things of type SomeAbstractClass, whereas you couldn't previously.
The situation is kind of like this:
// not actually how default interface members are implemented under the hood,
// just for illustration purposes only
public interface ISomeInterface
{
int Method();
}
public abstract class SomeAbstractClass : ISomeInterface {
public int Method() => 1;
}
public class SomeClass : SomeAbstractClass
{
public int Method() => 2; // this method obviously does not implement ISomeInterface.Method!
}
internal interface I_Foo
{
void Bar();
}
public abstract class A_Foo : I_Foo
{
public A_Foo() { }
abstract void I_Foo.Bar();
}
public class Foo : A_Foo
{
public Foo() : base() { }
internal override void Bar()
{
}
}
Hello! I'm trying to have some methods visible to outside code, and other only visible to my assembly. For this purpose, I made an internal interface I_Foo to serve as a contract to other parts of the assembly, a public abstract A_Foo to serve as abstraction for external code, and centralize some constructor functionality, and several different classes Foo that implement A_Foo and I_Foo explicitly to retain internal modifier.
However, in the A_Foo class, I get
'A_Foo.I_Foo.Bar()' must declare a body because it is not marked abstract, extern, or partial
even though the method is clearly marked as "abstract". If I add a body, I get "abstract is not a valid modifier".
I need this method to be explicitly declared, in order to be internal in a public class, and I need it to be abstract so I can override it in the actual implementation Foo.
Why doesn't the compiler let me?
Is there another way I can achieve the same thing?
Thank you.
Explicit interface implementations always have to have an actual implementation. The trick here is to making that just call a non-explicit (internal) abstract method:
public abstract class A_Foo : I_Foo
{
// Classes outside the assembly can't derive from A_Foo
// anyway, so let's make the constructor internal...
internal A_Foo() { }
void I_Foo.Bar()
{
Bar(); // Just delegate to the abstract method
}
internal abstract void Bar();
}
This still allows I_Foo to use internal types etc, because Bar is never exposed publicly - but it fits within the other rules of the language.
The method can not be abstract. THe problem is that you try to use explicit interface implementation (void I_Foo.Bar). Those methods can not be overwritten later - so they have to be implemented.
If you declare Bar directly (void Bar()) then it can be abstract.
Is it possible to create an abstract method that must return an instance of the derived class? I can do this:
abstract class Base
{
public abstract Base GetObj();
}
class Derived : Base
{
public Derived() { }
public override Base GetObj()
{
return new Derived();
}
}
But I was wondering if there was a way to do it such that Derived::GetObj() is forced to return a Derived?
Thanks.
Using generics should make this possible:
abstract class Base<T>
where T : Base<T>
{
public abstract T GetObj();
}
class Derived : Base <Derived>
{
public Derived() { }
public override Derived GetObj()
{
return new Derived();
}
}
You could even simplify this even more (if all of the derived instances are created with default constructors):
abstract class Base<T>
where T : Base<T>, new()
{
public static T GetObj()
{
return new T();
}
}
class Derived : Base<Derived>
{
public Derived() { }
}
What you have is almost but not quite exactly an abstract factory. I will first say that you should leave it up to the implementers of the derived classes to get it right, or simply trust that they will.
Another answer has shown what is known as the curiously recurring template pattern. It is where you have a base class that tries to use the type system to enforce that derived types use itself at certain input or output positions.
public abstract class Foo<T> where T : Foo<T>
public class Bar : Foo<Bar>
This idea might work in other languages. It works in C# only so far as people use it correctly. With the above definition of Bar, now I can also have
public class Baz : Foo<Bar>
Which is perfectly legal. Bar is a Foo<Bar>, which is all that is required for Baz to use it. Nothing requires Baz to actually use Foo<Baz>.
The type system in C# simply cannot enforce what you would like enforced. Even with this pattern in place, you are still in the same position as before. You still have to trust the implementers of the derived classes to do it correctly.
For more on this topic, you might read this blog.
I have code
internal interface IFoo
{
void foo();
}
public class A : IFoo
{
// error CS0737: 'A' does not implement interface member 'IFoo.foo()'.
//'A.foo()' cannot implement an interface member because it is not public.
internal void foo()
{
Console.WriteLine("A");
}
}
Why such strange limitation? I have internal interface and why I can't create internal method in interface realization?
This is because interfaces can't specify anything about the visibility of members, only the members themselves. All members that implement an interface must be public. The same happens when you implement a private interface.
One solution might be explicitly implementing the interface:
internal interface IFoo
{
void foo();
}
public class A : IFoo
{
void IFoo.foo()
{
Console.WriteLine("A");
}
}
In the above code, you must have an instance of A cast to IFoo to be able to call foo(), but you can only do such a cast if you are internal compared to the class and hence have access to IFoo.
I have this class/interface definitions in C#
public class FooBase {
...
protected bool Bar() { ... }
...
}
public interface IBar {
bool Bar();
}
Now I want to create a class Foo1 derived from FooBase implementing IBar:
public class Foo1 : FooBase, IBar {
}
Is there some class declaration magic that the compiler takes the inherited protected method as the publicly accessible implementation of the interface?
Of course, a Foo1 method
bool IBar.Bar()
{
return base.Bar();
}
works. I'm just curious whether there is a shortcut ;)
Omitting this method results in a compiler error: Foo1 does not implement interface member IBar.Bar(). FooBase.Bar() is either static, not public, or has wrong return type.
Explanation: I separate code inheritance (class hierarchy) and feature implementation (interfaces). Thus for classes implementing the same interface, accessing shared (inherited) code is very convenient.
No shortcut. In fact, this pattern is used in a few places I've seen (not necessarily with ICollection, but you get the idea):
public class Foo : ICollection
{
protected abstract int Count
{
get;
}
int ICollection.Count
{
get
{
return Count;
}
}
}
I believe your code is as short as it can be. Don't think there is any kind of shortcut out there.
The protected member FooBase.Bar() is not an implementation method of the interface IBar. The interface demands a public Method Bar().
There are 2 ways implementing an interface. Explicit implementation or implicit implementation.
Following is explicit implementation. This method is called if an object of Foo is called through a IBar variable.
bool IBar.Bar()
{
return base.Bar();
}
Defining a public method Bar() is implicit implementation.
To have the compiler satisfied you might override or new the baseclass method as public (not a good advise, if method is protected in baseclass).
new public bool Bar()
{
return base.Bar();
}
The trick is to implement an interface, but not having all interface members as public members in the class.