Why do you write a subclass? To add stuff. Different subclasses will add different stuff (or you'd only need one). If you have a reference to the base class, it might refer to an instance of the subclass you have in mind, but it might refer to something else entirely. And what happens then? You'll be trying to interact with a feature the object doesn't even have. Dynamic languages like JavaScript let you do things like that, but strongly typed languages like C# don't, by design. On a large project, this turns out to be very useful. The compiler is keeping an eye on what goes where, so you as the programmer don't have to spend your life writing code that needs to figure out what things are.
class Mammal {
public void Nurse() { /* */ }
}
class Dog : Mammal {
public void ChaseCar() { /* */ }
}
class Cat : Mammal {
public void ClimbTree() { /* */ }
}
Mammal myPet = new Cat();
// The actual object which myPet refers to may not be a Dog, so the
// compiler won't let you do this. The declared type of the reference,
// Mammal, is an implicit guarantee that, unless it's null, it's
// referring to something that can be treated as a Mammal.
myPet.ChaseCar();
// You can force it to try, but in this case, myPet does not refer
// to a Dog, so this call will fail at runtime and throw an exception.
((Dog)myPet).ChaseCar();
// But C# does let you find out what you've really got. In this case,
// myPet is not Dog, so this block won't execute. But if it were a
// Dog, it would. In the general case, that can only be determined at
// runtime. In principle the compiler could make an exception for
// cases where the actual runtime type of myPet can be known at
// compile time -- as in this example code -- but my guess is that
// the compiler designers would see that as adding more complexity
// and confusion than it would be worth.
if ( myPet is Dog ) {
Dog myDog = myPet as Dog;
myDog.ChaseCar();
}
Consider this case: Anybody could be passing anything to this method. animal could actually be a Baboon or a Giraffe.
public void CarDrivesBy(Mammal animal) {
// What is animal? At this point, you can't know, the compiler
// can't know, so it won't accept this.
animal.ChaseCar();
}
If you want to treat animal as a dog, you can ask the compiler to help guarantee that you're getting a Dog, and then treat it as one with (relative) confidence:
public void CarDrivesBy(Dog animal) {
// Now the compiler knows what you want, and enforces that on
// anybody who calls this method.
animal.ChaseCar();
}
Also, just parenthetically, the word "scope", as it is used in programming, refers to a completely unrelated concept.
studentisschoolStudent?