Why can an abstract class not be sealed or static? - c#

Why can an abstract class not be sealed or static?
And I am also confused about the question Why declare static classes as sealed and abstract in C#?.

static class cannot be marked sealed because it is made sealed by compiler by default.
Static classes are sealed and therefore cannot be inherited.
static class cannot be marked as abstract, because it would be pointless. abstract class makes sense when you want all derived classes to implement same part of the logic. But because static class cannot be derived there is no way other class will implement these gaps.
They cannot inherit from any class except Object.
Both quotes from Static Classes and Static Class Members (C# Programming Guide).
C# specification is a little more detailed about that:
10.1.1.3 Static classes
A static class may not include a sealed or abstract modifier. Note, however, that since a static class cannot be instantiated or derived from, it behaves as if it was both sealed and abstract.
You can read what does it mean for class to be sealed or abstract:
An abstract class cannot be instantiated directly, and it is a compile-time error to use the new operator on an abstract class
The sealed modifier is used to prevent derivation from a class. A compile-time error occurs if a sealed class is specified as the base class of another class.
Update
And a word about an article linked in the query you mentioned (Static Class Design). It's already stated in accepted answer from that question. If you read carefully you can see that:
√ DO declare static classes as sealed, abstract, and add a private instance constructor if your programming language does not have built-in support for static classes.
.NET (so C# as well) do have built-in support for static classes, so you don't have (and even can't) to make your classes pseudo-static by marking it both sealed and abstract.

First of all, let's start with a definition; sealed is a modifier which if applied to a class make it non-inheritable and if applied to virtual methods or properties makes them nonoverridable.
public sealed class A { ... }
public class B
{
...
public sealed string Property { get; set; }
public sealed void Method() { ... }
}
An example of its usage is to define a specialized class/method or property in which potential alterations can make them stop working as expected (for example, the Pens class of the System.Drawing namespace).
...
namespace System.Drawing
{
//
// Summary:
// Pens for all the standard colors. This class cannot be inherited.
public sealed class Pens
{
public static Pen Transparent { get; }
public static Pen Orchid { get; }
public static Pen OrangeRed { get; }
...
}
}
Because a sealed class cannot be inherited, it cannot be used as base class and by consequence, an abstract class cannot use the sealed modifier.
It's also important to mention that structs are implicitly sealed.

Related

Abstract method in public abstract class implementing an internal interface doesn't compile?

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.

What does a public constructor on an internal class mean [duplicate]

This question already has answers here:
What's the difference between a public constructor in an internal class and an internal constructor?
(5 answers)
Closed 9 years ago.
I've seen some C# code that declares a class with an internal modifier, with a public constructor:
internal class SomeClass
{
public SomeClass()
{
}
}
What is the point of having a public constructor, if the visibility of the entire class is internal, thus it can be seen only inside the defining assembly?
Also, does this make any sense in case SomeClass is a nested class?
The internal class scope overrides the public MyClass() constructor scope, making the constructor internal.
Using public on the constructor makes it easier to update the class to public later, but confuses intent. I don't do it.
Edit 3: I missed part of your question. It is still fine to do that if your class is nested. The nesting can't make any difference, even if it is nested in a private class in a public class in a ... (see C# language specification - 3.5.2 Accessibility domains).
EDIT: And, if i recall, if the ctor is internal, it can't be used as a generic type where there is a constraint requiring where T : new(), this would require a public constructor (ref. C# language specification (version 4.0) - 4.4.3 Bound and unbound types).
Edit 2: Code sample demonstrating the above
class Program
{
internal class InternalClass {
internal InternalClass() { }
}
internal class InternalClassPublicCtor {
public InternalClassPublicCtor() { }
}
internal class GenericClass<T>
where T : new() {}
static void Main(string[] args) {
GenericClass<InternalClass> doesNotCompile = new GenericClass<InternalClass>();
GenericClass<InternalClassPublicCtor> doesCompile = new GenericClass<InternalClassPublicCtor>();
}
}
From MSDN - Access Modifiers (C# Programming Guide):
Normally, the accessibility of a member is not greater than the accessibility of the type that contains it. However, a public member of an internal class might be accessible from outside the assembly if the member implements interface methods or overrides virtual methods that are defined in a public base class.
So if, for example, you have an internal implementation of a public interface, you can still expose certain members as public.
Additionally, suppose you suddenly want your internal class to be public. It's a lot easier simply to change the access modifier on the class than all of the members.

What is an internal sealed class in C#?

I was looking through some C# code for extending language support in VS2010 (Ook example). I saw some classes called internal sealed class
What do these do? Would one use them?
It is a class that:
internal: Can only be accessed from within the assembly it is defined (or friend assemblies).
sealed: Cannot be inherited.
Marking classes as internal is a way of preventing outside users of an assembly from using them. It's really a form of design encapsulation and IMHO it is good practice to mark types that are not part of the intended public API\object models as internal. In the long term this prevents users of your library from coupling themselves to types which you did not intend them to. This sort of unintended coupling harms your ability to change and evolve the way your libraries are implemented as you cannot change them without breaking your clients. Using internal helps to keep the public and usable surface area of a library down to what is intended.
Marking classes as sealed prevents these classes from being inherited. This is a pretty drastic design intent which is sometimes useful if a class is already so specialized that it is sensible that no other functionality should be added to it via inheritance either directly or via overriding its behaviour.
internal and sealed modify types in quite different ways, but they can be used together.
NB You have some further scoping control of internal as you can define a set of other assemblies as 'friends'. These friend assemblies may access your internal types. This can be useful for defining sets of co-operating assemblies such as production and test assemblies. It is often desirable that a test assembly can see all the types in the assembly it is testing.
internal: A class which can only be accessed inside the same assembly.
Assembly1.dll:
namespace test {
internal class InternalClass {
}
public class PublicClass {
}
}
Assembly2.dll:
using test;
...
InternalClass c1; // Error
PublicClass c2; // OK
sealed: A class which cannot be derived from
sealed class SealedClass { ... }
class ChildClass : SealedClass {} //ERROR
Internal means the member is accessible to other types that are defined in the same assembly. A Sealed class is sort of the oppositie of abstract. It can be instantiated but cannot serve as a base class. The primary reason to seal a class is to prevent your users from fiddling around with it and breaking it. It’s also the case that sealing a class permits certain compiler optimizations that are not possible with non-sealed classes.
An internal sealed class is one that is:
internal - Only accessible from within the same assembly
sealed - Cannot be subclassed
In other words, there's no way for you to use it directly.
Internal means it can be used only in same assembly,
The internal keyword is an access
modifier for types and type members.
Internal types or members are
accessible only within files in the
same assembly
sealed that can't be inherited
A sealed class cannot be inherited. It
is an error to use a sealed class as a
base class. Use the sealed modifier in
a class declaration to prevent
inheritance of the class.
INTERNAL
Internal types or members are accessible only within files in the same assembly.
Example
// Assembly1.cs
// Compile with: /target:library
internal class BaseClass
{
public static int intM = 0;
}
// Assembly1_a.cs
// Compile with: /reference:Assembly1.dll
class TestAccess
{
static void Main()
{
var myBase = new BaseClass(); // compile error
}
}
SEALED
First of all, let's start with a definition; sealed is a modifier which if applied to a class make it non-inheritable and if applied to virtual methods or properties makes them non-ovveridable.
public sealed class A { ... }
public class B
{
...
public sealed string Property { get; set; }
public sealed void Method() { ... }
}
An example of its usage is specialized class/method or property in which potential alterations can make them stop working as expected (for example, the Pens class of the System.Drawing namespace).
...
namespace System.Drawing
{
//
// Summary:
// Pens for all the standard colors. This class cannot be inherited.
public sealed class Pens
{
public static Pen Transparent { get; }
public static Pen Orchid { get; }
public static Pen OrangeRed { get; }
...
}
}
Because a sealed class cannot be inherited, it cannot be used as base class and by consequence, an abstract class cannot use the sealed modifier. It's also important to mention that structs are implicitly sealed.
Example
public class BaseClass {
public virtual string ShowMessage()
{
return "Hello world";
}
public virtual int MathematicalOperation(int x, int y)
{
return x + y;
}
}
public class DerivedClass : BaseClass {
public override int MathematicalOperation(int x, int y)
{
// since BaseClass has a method marked as virtual, DerivedClass can override it's behavior
return x - y;
}
public override sealed string ShowMessage()
{
// since BaseClass has a method marked as virtual, DerivedClass can override it's behavior but because it's sealed prevent classes that derive from it to override the method
return "Hello world sealed";
}
}
public class DerivedDerivedClass : DerivedClass
{
public override int MathematicalOperation(int x, int y)
{
// since BaseClass has a method marked as virtual, DerivedClass can override it's behavior
return x * y;
}
public override string ShowMessage() { ... } // compile error
}
public sealed class SealedClass: BaseClass {
public override int MathematicalOperation(int x, int y)
{
// since BaseClass has a method marked as virtual, DerivedClass can override it's behavior
return x * y;
}
public override string ShowMessage()
{
// since BaseClass has a method marked as virtual, DerivedClass can override it's behavior but because it's sealed prevent classes that derive from it to override the method
return "Hello world";
}
}
public class DerivedSealedClass : SealedClass
{
// compile error
}
Microsoft documentation
Sealed: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/sealed
Internal: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/internal

Is it good to have a constructor in abstract class?

Is it good to have a constructor in abstract class?
is it a good programming practice to create constructor of abstract class? since abstract classes can not be initialized, their child classes are initialized.
Following is my class structure.
public abstract class Scheduler
{
private Storyboard timer;
protected Scheduler()
{
// initialize the timer here.
timer = new Storyboard();
this.PollInterval = 60;
}
}
public class TaskScheduler : Scheduler
{
public TaskScheduler()
: base()
{
}
}
Yes, it's absolutely fine. Just because the constructor can only be called by derived classes doesn't mean it won't be useful. For example, you might have an abstract class which represents a named entity of some kind - it would make sense to take the name as a constructor parameter.
It would probably be worth making the constructor protected, to make it even more obvious that you can't just call it from elsewhere.
Note that there being a constructor (or multiple constructors) in an abstract class does force derived class constructors to go through it, but it doesn't force the derived classes to have the same constructor signatures. For example:
public abstract class NamedFoo
{
private readonly string name;
public string Name { get { return name; } }
protected NamedFoo(string name)
{
this.name = name;
}
}
public class DerivedFooWithConstantName
{
public DerivedFooWithConstantName() : base("constant name")
{
}
}
In this case the derived class constructor is "removing" a parameter (by providing a constant value as the argument to the abstract class constructor) but in other cases it could "add" parameters that it required, or have a mixture.
There is absolutely no reason not to have a constructor in an abstract base class.
The abstract class is initialized and works just like any other class. The abstract keywords only do the following:
It prevents the class itself to be instantiated directly. It can only be instantiated by instantiating an inherited class. This does not change the behavior of initialization compared to a not abstract base class;
It allows you to have abstract methods, properties and events in the class.
If you e.g. do not have abstract methods, properties or events, exactly the same result can be accomplished by making the constructor of a class protected (like you did). This also prevents the class to be instantiated directly. The behavior does not change however compared to an abstract class.
The primary difference then becomes the ability to declare methods, properties and events as abstract which you can only do when the class is marked abstract.
Having constructor in abstract class can be useful at times. This question is a duplicate, and dealt great deal in an related post. Even though it specifically reference JAVA, conceptually it applies to C# also.
Can an abstract class have a constructor?
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. CA1012: Abstract types should not have constructors
Fix the violation by changing the accessibility of the constructor from public to protected.
Example:
namespace Sample
{
public abstract class Book
{
protected Book()
{
}
}
}

Abstract class constructor in C#

In c# we can't create an obeject of a abstact class or interface it means abstract class do not have any constructor, is it true ?
or if it have then what is it's purpose there?
As others have said, abstract classes usually have constructors (either explicitly or the default one created by the compiler) - and any derived class constructor will have to chain through the abstract class's constructor in the normal way. That's the important bit... suppose you have an abstract class which stores the name associated with an instance - because you always want a name, and you don't want to write the Name property in each concrete derived class. You might provide a constructor which takes that name and assigns it to a field... and then every subclass constructor would have to go through that constructor, so that you still knew you'd always have a name. If you want to know more about constructor chaining, read my article on it.
Here's an example of that:
public abstract class DemoBase
{
private readonly string name;
public string Name { get { return name; } }
protected DemoBase(string name)
{
this.name = name;
}
// Abstract members here, probably
}
public class FixedNameDemo : DemoBase
{
public FixedNameDemo()
: base ("Always the same name")
{
}
// Other stuff here
}
public class VariableNameDemo : DemoBase
{
public VariableNameDemo(string name)
: base(name)
{
}
// Other stuff here
}
To further answer your comment on BoltClock's answer, asbtract classes can't have private abstract methods, but they can have private constructors. Indeed, it's sometimes useful to have only private constructors in an abstract class, because it means the class can only be derived from within the program text of the same class. This allows you to create pseudo-enums:
public abstract class ArithmeticOperator
{
public static readonly ArithmeticOperator Plus = new PlusOperator();
public static readonly ArithmeticOperator Minus = new MinusOperator();
public abstract int Apply(int x, int y);
private ArithmeticOperator() {}
private class PlusOperator : ArithmeticOperator
{
public override int Apply(int x, int y)
{
return x + y;
}
}
private class MinusOperator : ArithmeticOperator
{
public override int Apply(int x, int y)
{
return x - y;
}
}
}
In this respect, an abstract private method/property could make sense - it could be accessed by the base class but provided by the derived classes within the same class's program text. However, it's prohibited by the specification. Usually, protected abstract members would solve the same problem - but not quite always.
Good question. Here's why Abstract classes need constructors even though they cannot be instantited.
In any Object oriented language like C#, object construction is an hierarchical process. Look at the code below. When you instantiate any object of type DerivedClass, it must construct the base object first before creating the object of typeof DerivedClass. Here the base class may or may not be an Abstract class. But even when you instantiate an object of a concrete type derived from an abstract class it will still need to call the constructor of the Base class before the object of DerivedClass type is created, hence you always need a constructor for Abstract class. If you have not added any constructor, C# compiler will automatically add a public parameterless constructor to the class in the generated MSIL.
public class BaseClass
{
public BaseClass()
{
Console.WriteLine("BaseClass constructor called..");
}
}
public class DerivedClass : BaseClass
{
public DerivedClass()
{
Console.WriteLine("DerivedClass constructor called..");
}
}
DerivedClass obj = new DerivedClass();
//Output
//BaseClass constructor called..
//DerivedClass constructor called..
PS: Assuming, If Abstract base classes
are not allowed to have constructors
because they need not be instantiated,
the whole fundamentals of the object
oriented programming will go on toss.
The idea behind Abstract types are to
represent objects that have some
features and behaviours but not
complete as whole to allow independant
existence.
No. it means that operator new is not allowed to create object from this type of class.
The purpose might be that are allocated/initialized some properties of class.
abstract usually leave some methods to implement.
Regarding the interface, this structure holds only the signatures of method, delegates or events. That may be implemented in class that use interface. You cant create a object.
Read about new
EDIT:
What is the purpose of constructor in abstract class ?
When one class inherit another class, the parent class of it had to be created first while object is crated. In class do not implement some special constructor always is used default one [className()]. When you override some method then the implementation of functionality is taken form class which override the method. This is why method used in constructor should never be virtual. Same logic for abstract class, such class can have a lot of functionality, and only one method that should be implemented by child class.
Abstract classes have constructors but you can't call them directly as you can't directly instantiate abstract classes.
To answer your comment, the concept of a private abstract method or property makes no sense, because private prevents anybody else from accessing it, and abstract prevents itself from accessing it. So there would essentially be no possible way to call it.
EDIT: see Jon Skeet's answer on private constructors. Private members of other kinds cannot exist in abstract classes, though.
Abstract classes do have constructors. When you create an instance of a derived class, its parent class' constructors are called. This applies to classes derived from abstract classes as well.

Categories