Neither is instantiable. What are the differences, and in what situations might you use one or the other?
Here is a short summary:
static
members (it is just a container for methods that do not logically belong to an instance of any standard class)The key difference is that you can inherit from an abstract
class, but you cannot inherit from a static
class. Technically speaking, the .NET runtime doesn't have any notion of static
classes, so the C# compiler compiles them as classes that are both abstract
and sealed
(meaning that you cannot inherit from them).
So, static
classes are abstract
classes that are also sealed
(although this is not the usual way to look at the problem if you are C# programmer) and contain only static
members (which is enforced by the C# compiler).
The CLR has no notion of static classes, it is specific to C#. The compiler implements it by slick use of CLR attributes for a class: it declares it abstract and sealed. That prevents any language from instantiating such a class. This is what it looks like when you run Ildasm:
.class public abstract auto ansi sealed beforefieldinit ConsoleApplication1.Test
extends [mscorlib]System.Object
{
}
Making it sealed is very much the point of a static class, it is used as a container for static methods and fields. Which makes them act like global variables and functions like you have in languages like C or Pascal.
An abstract class is very much the opposite, it is designed to be derived from. A abstract class that has all of its member abstract acts like an interface. C# has a keyword for that, making static class and interface the exact opposites.
Abstract classes are intended to be used as base classes; they cannot have direct instances. Instead, you have to derive subclasses, which provide the what was (usually intentionally) left out in the abstract base class.
Example: consider you have a complex application, where users may log-in to. Various authentication mechanisms should be usable, say, LDAP, NTLM, you name it. One way to model a "user" or "principal" in such a context would be to collect, what is common across all those mechanisms, into an abstract base class, and leave "gaps" (abstract methods) where the actual implementations come into play:
abstract class Authenticator {
protected Dictionary<string,User> userCache;
...
public User LoadUser(string name) {
User user;
if( userCache.TryGet(name, out user) ) return user;
else {
user = LoadFromStore(name);
userCache.Add(name, user);
return user;
}
}
protected abstract User LoadFromStore(string name);
}
Here, caching of users is a common concern, modelled in the base case, whereas the actual retreival is left for a subclass to provide.
Static class are a different matter alltogether. They are essentially a place to keep your utility functions:
static class StrUtil {
public static string TrimWhitespace(string str) {
...
}
}
Think of them as some kind of special namespace, which can only contain static members. Basically, a place to put functions.
Main difference between the two is extensibility.
CLR marks all 'static' classes as 'abstract & sealed' behind the scene (i.e., they cannot be inherited hence cannot be extended) and .NET Framework CLR loads them automatically when containing program or namespace is loaded. This gives performance gain on runtime.
Philosophy behind 'abstract' classes is capitalizing all common features of all extended classes in one place.
Hope it helps.
Abstract classes get instantiated indirectly via derived classes. They provide common behaviour and instance state, but signal that more is required and must be provided by derived concrete classes. For example, Transform
might be an abstract class: it declares a common Apply(Shape)
method, but no implementation of that method. Concrete derived classes like Rotation
or Translation
will implement that method, and those classes can be instantiated.
Static classes cannot be instantiated, and any state is at the class level rather than the instance level. They are typically used to define utility methods where there is no state associated with the methods. Transform
couldn't be a static class, because the concrete derived classes need per-instance state (e.g. Rotation
needs a per-instance Angle
, because different Rotation
transforms could be by different angles).
Abstract class main purpose is to define one or more abstract method(s). Any class extending Abstract class will implement the abstract method or else its also need to be declared as "Abstract".
But, its also possible to declare a class as "Abstract" without implementing any abstract method(s) in it. See the sample below.
public abstract class AbstractTest {
public void abcd(){}
public static void main(String[] args) {
System.out.print("hi...");
}
}
Only inner class can be declared as "Static", see the code below. Upper/encapsulating class can't be declared as "Static". It can be accessed by using Upper/encapsulating class variable.Static-inner-classname i.e same as any static method invocation using class name.
public class StaticTest {
public static void main(String ag[]){
System.out.println("hello...1");
StaticTest.StaticTest2.meth2();
}
public static class StaticTest2 {
public static void meth2(){
System.out.print("hello...2");
}
}
}