In this section I want to review some basic object-oriented concepts to ensure that we are all on the same page. If you are sure you understand the difference between a metaclass, a class, and an object and you know what encapsulation and information hiding, association, aggregation, inheritance, and polymorphism are, skip to the last section in this chapter to read about the ildasm.exe utility. If you need to review these concepts, stay tuned .
Objects, Classes, and Metaclasses
Occasionally I hear things that are astounding. I was at a user 's group in Charlotte, North Carolina, and heard a smart person say to a group of a hundred or so developers that there is "no difference between a class and an object." Not a single person challenged him. I hope this was out of politeness, but I have heard this often enough when talking to other VB programmers that I can understand if there is some confusion.
Just in case you are not sure, there is a world of difference between a class and an object. In the physical world a class is akin to the blueprint of a house, and an object is akin to a house built following that blueprint. The difference between classes and objects is similar to the fact that no one wants to live in a blueprint.
Classes describe things and objects are instances of those things. That is, for the most part, objects have memory and state and classes do not. This is where it can become confusing again, but only a little bit.
What about shared members? Shared members can record state, and shared members can be invoked. Precisely so. When a class is used in this manner, like an object, we refer to that as a metaclass . Metaclasses are classes used as if they represented an object. Usually, though, a class is a description of a thing and an object is an instance of that thing.
Information Hiding and Encapsulation
Encapsulation is when we make fields, properties, methods , and events become members of types. We say that the type encapsulates the member. Encapsulation deals with the concept of part and whole. Members are part of types, the whole.
Information hiding refers to when we employ access modifiers to logically conceal members from consumers. The more restrictive the access modifier, the more information we are hiding. Again, like first dates, the less we reveal about a class the better. Of course, if you don't reveal anything, there is no second date. (I'm not going to try to come up with an arranged marriage analogy.) When it comes to information hiding you want to reveal enough to secure a second date but never as much as you would reveal if married.
As a general rule, apply this test: Classes should introduce approximately a half-dozen public members. If you have significantly more than that, you should split up the class. If you have markedly fewer than a half- dozen members, you should consolidate the class. The number of nonpublic members should be whatever is sufficient to support the public members.
Association, Aggregation, and Inheritance
Association refers to a relationship where one object refers to an instance of another object but is not responsible for creating that other object. Unidirectional association means that only one class is aware of the other, and bidirectional association means that both objects in the relationship are mutually aware of, but not responsible for, each other.
Aggregation refers to containment. When one object contains a reference to another and is responsible for constructing that other object, this is called aggregation. (Sometimes this is referred to as composition .)
Inheritance refers to one class having members of another class. The class inherited from is referred to as the parent or superclass , and the class inheriting is referred to as the child or subclass .
Unlike VB6, VB .NET implements actual inheritance. VB6 implemented interface inheritance.
Polymorphism has to do with inheritance. When a parent class is defined, the parent may introduce a method named Foo . A subclass may introduce an extended version of Foo . Which Foo is invoked depends on whether we have an instance of the parent or the child. A reasonable person might wonder why it would ever depend on whether we had the parent or the child. The answer is that sometimes we don't know or care whether we are dealing with a parent or a child. We want to write code in such a way that it doesn't matter.
Let's take an example. The Object class (sounds a bit ridiculous to say " Object class," doesn't it?) in VB .NET introduces a method called GetType . With it you can request type information for the Object class. Consequently every class has a GetType method. However, if we are dealing with Button we do not want Object 's type record; we want Button 's. We do not need to know the type of the class (all we need is an instance) for GetType to return the correct type record ”that's polymorphism.
Polymorphism is based on doing the right thing without knowing the type of an object. The theoretical implication is that we can define methods that interact with the most general type but perform correctly when they are presented with a more specific type. The technical implication is that there exists ”created by the compiler ”an array of methods, referred to as a virtual methods table , and a mechanism that knows how to index the array of methods to find the right method. So, even if you have a variable reference whose type is Object , you can assign a subtype to that variable and methods in common will behave correctly based on the actual type rather than the declared type.