So I have an abstract base class in a DLL and child classes of that class. I want the childs to be public, but the base to be private so that it cannot be accessed outside of the dll.
How do I do that?
You don't and you can't.
If you want to expose the class as public, the base-type must be public. One other option is to have a public interface, and only expose the type via the interface (presumably with a factory method somewhere for creating instances).
One final option is to encapsulate the base-class rather than inherit it.
Make it public, make all constructors internal (if you're using the default constructor, add a parameterless constructor to override that).
Then while public and not sealed, it can't be sub-classed by external code.
Just to clarify what I was saying in comments on #Marc Gravel's answer you could
public ChildClass : ParentClass
{
}
public ParentClass
{
internal void MethodIdontWantToExpose()
{
}
}
That said an interface is probably the best solution
Related
http://msdn.microsoft.com/en-us/library/ms182126.aspx
Microsoft Design Guidelines say that Abstract Types should not have a Constructor.
To me, it seems very plausible that most classes that derive from an abstract class will have a constructor very similar to, if not identical to, its base.
If for no other reason but to follow DRY, is it really terrible to have abstract classes with Constructors if it means that all your derived classes now only need to put
public DerivedClass()
: base()
{
}
Or is there something that I am missing?
There's nothing to prevent you from doing that but by definition abstract classes are those that cannot be instantiated. So if you create a constructor, make it protected, not public otherwise your class won't meet the definition of abstract.
The guideline you mentioned further explains:
Cause: A public type is abstract and has a public constructor.
and
Rule description: Constructors on abstract types can be called only by derived types. Because public constructors create instances of a type, and you cannot create instances of an abstract type, an abstract type that has a public constructor is incorrectly designed.
How to Fix Violations: To fix a violation of this rule, either make the constructor protected or do not declare the type as abstract.
Constructors of an abstract class shouldn't be public and they should be protected. My question is about methods in that abstract class. Can we declare them as public or they should be protected too for the same reason?
The justification for constructors on abstract types being protected is that there is simply no other entity that could call the constructor other than a derived type. Making the constructor public is meaningless in this case as it can't ever be invoked outside the type hierarchy. Hence the recommendation is to use protected as it's the most appropriate access modifier.
The same logic doesn't hold true with other members on the type. They can be freely invoked from outside the type hierarchy should their access modifier permit it.
public abstract class Dog {
// Public is appropriate here as any consumer of Dog could access
// Breed on an instantiated object
public abstract string Breed { get; }
// Public would be meaningless here. It's not legal to say
// 'new Dog' because 'Dog' is abstract. You can only say
// 'new Poodle' or 'new Bulldog'. Only derived types like
// Poodle or Bulldog could invoke the Dog constructor hence it's
// protected
protected Dog() { }
}
public class Poodle : Dog { }
public class Bulldog : Dog { }
Whether or not a particular member should be public or protected is highly dependent upon the particular API. The reasoning should be the exact same for abstract types as it is for non-abstract types
Abstract classes shouldn't have public constructors because they don't make sense. Abstract classes are incomplete, so allowing a public constructor (which anyone could call) wouldn't work as you can't instantiate an instance anyway.
Methods on abstract classes are another story. You can have implementation in an abstract class, which is the behavior that all subclasses will inherit. Think of a Shape class. Its purpose is to draw a shape on the screen, so it makes sense to make a Draw method public as you'll want callers to be able to ask your Shape to draw. The method itself can be abstract, forcing subclasses to implement, or possibly provide an implementation which may or may not allow overriding. It depends on what the defined behavior of your class should be.
It depends on your use case. If you want the methods of the abstract class visible to instances of your derived class, you should make them public. If, on the other hand, you want the methods visible only to your derived class, you should make them protected.
I had created a base class that has many public properties and were been used perfectly. Now i want to use this class to derive other class , but i do'nt want some of its properties to be exposed outside the derived class that inherits it. Is there any way that the properties of base class that are public cannot be exposed outside its derived class.(The properties that are to be hidden are public because they are used in other classes that inherits it).Any help will be highly appericiated.
You want to make them protected.
From MSDN:
A protected member is accessible within its class and by derived class instances.
I agree with cadrell0 about marking them protected, but just in case you are looking for a solution where the properties are actually public, but hidden to users of a certain derived class, you can use an explicit interface
interface IHaveMethodsYouCanHide { void Foo(); }
class Base : IHaveMethodsYouCanHide { public void Foo() {} }
class NonHidingDerived : Base { }
class HidingDerived : Base, IHaveMethodsYouCanHide
{
void IHaveMethodsYouCanHide.Foo() {}
}
With this code, identifers of type HidingDerived will not allow calls to Foo (unless first cast to IHaveMethodsYouCanHide).
What you're asking for is simply not possible. If type B inherits from type A then it "is-a" type A. B has at least the same accessible contract that type A had. There is no way to hide a public member of A without fundamentally violating this contract.
If you find yourself in a scenario where you want to use A but only expose a subset of the properties then inheritance is not the right solution: containment is the proper solution.
public class B {
private A m_wrapped;
// Expose only the properties you want to expose here
}
There is some mechanism to allow a class to be inherited by N classes only in C#?
You may put it and it's derived classes in a separate assembly, and declare the constructor of the base class as internal. That way although you could inherit from it in a different assembly, but you wouldn't be able to instantiate any derived class.
No, but you can always make the constructor throw an exception if it exceeds the limit.
// can be inherited only by classes in the same assembly
public abstract class A
{
protected internal A() { }
}
// can't be inherited
public sealed class B : A
{
}
Just for my personal edification, I'd like to know more about the business context which make such a design choice desirable, since my first thougt at reading the title was "Oh, very very bad idea ! A base class is NEVER supposed to know anything (and worse : to rule) its derived classes".
You can make the class A abstarct and inherit it in any number of classes..
I am surprised to know that an abstract class in C# is possible with no abstract methods also.
abstract class AbstractDemo
{
public void show()
{
Console.WriteLine("In Show Method");
}
}
class MainDemo:AbstractDemo
{
public static void Main()
{
Console.WriteLine("In Main Method");
}
}
Any explaination ?
Sometimes you don't want to give the possibility to instantiate a class but you need this class as a base class for other classes.
The reason for choosing abstract classes over interfaces is that you can provide some basic implementation.
This is entirely valid, and occasionally useful if you want to provide event-like behaviour: provide an abstract class with all the "event handlers" implemented as virtual methods with a default behaviour of doing nothing.
I've also personally used this a lot for abstract remote API client classes where all methods throw exceptions: they're abstract for the purposes of test doubles, expecting our implementations to be the only production implementations, but allowing users to create their own test doubles either by hand or via mocking frameworks. Making the methods virtual instead of abstract means that new RPCs can be added without that being a breaking change.
A derived class can then override some of the methods, but doesn't have to override any specific one, because nothing's abstract. It still makes sense for the class to be abstract because an instance of the base class would be pointless (as everything would be a no-op).
This pattern is much more common in Java than C#, however - as in C# you'd normally just use "proper" events.
An abstract class is a class that must be extended before it can be used. This does not it any way mean that the function themselves must be abstract.
Take for example an Animal class
public abstract class Animal
{
void Move()
{
//whatever
}
}
public class Fish : Animal
{
void Swim()
{
}
}
public class Dog : Animal
{
void Bark()
{
}
}
All animals can move but only the fish can swim and the dog can bark.
Or for a real life example. I have an Asp.net MVC base controller I use in my application. It has some basic methods I need very often like GetCurrentUser() and a function I wrote to help with localization. It also takes care of tracking so I don't have to rewrite that code in all of my controllers. The class has about 200 lines of code but not a single abstract method.
I think you're confusing abstract classes with interfaces. Interfaces can't have methods with body, abstract classes can. There are times when you want to prevent user from instantiating an object of a specific class; but still provide some base functionality for the classes that derive from it; this is what an abstract class is useful for.
If your class is just a base for other classes and it does not have an full usablility - in other words as a base itselfe is not usable at all then you want to prevent from creating instances of it. In this case you can make abstract class without abstract members.
You could use abstract keyword on a class just to signal the compiler that it can only used inheriting from it, and not directly; In this case you are not oblied to put abstract member on the class.
This is equivalent to put in the class only one protected constructor, but using abstract is more clear and understandable.
No better explanation than MSDN it self
http://msdn.microsoft.com/en-us/library/aa645615(v=VS.71).aspx
An abstract class cannot be instantiated directly, and it is a
compile-time error to use the new
operator on an abstract class. While
it is possible to have variables and
values whose compile-time types are
abstract, such variables and values
will necessarily either be null or
contain references to instances of
non-abstract classes derived from the
abstract types.
An abstract class is permitted (but not required) to contain abstract
members.
An abstract class cannot be sealed.
We have heard that in abstract class, there must be an abstarct member. But when I compile the abstarct class without an abstract method, it compiles. It gives me surprise. Now I am unable to find the article which explain exact behavior of an abstarct class.