i have to create a fake DMV program that calculates annual fees, for commercial and private vehicles. Those two classes will be abstract and they will polymophism from a class named all vehicles.
My instructor wants only one object created the entire program(in main) but since my top 3 tier classes are abstract. I can't create an object with them i.e. vehicles = new vehicles();
so my question is how do i create only one object since they are abstract? If you have any questions feel free to ask, I might have not explained this well...
Your class structure will look something like:
abstract class Vehicle
{
protected abstract int BaseFee { get; }
protected abstract int ExtraFee { get; }
public int CalculateFee()
{
return BaseFee + ExtraFee;
}
}
abstract class CommercialVehicle : Vehicle
{
protected override int BaseFee
{
return 100;
}
}
class LightDutyTruck : CommercialVehicle
{
protected override int ExtraFee
{
return 50;
}
}
class Semi : CommercialVehicle
{
protected override int ExtraFee
{
return 150;
}
}
[etc...]
abstract class PrivateVehicle : Vehicle
{
protected override int BaseFee
{
return 25;
}
}
class Sedan : PrivateVehicle
{
protected override int ExtraFee
{
return 15;
}
}
and so on, for each class. In your Main method, you would create the instance based on input, but your actual variable would be declared as type Vehicle. The actual calculation will take effect based on the instance that you create:
Vehicle v;
switch(input)
{
case "semi":
v = new Semi();
break;
case "truck":
v = new LightDutyTruck();
break;
...
}
int fee = v.CalculateFee();
You seem to be a bit confused. "All Vehicles" should be abstract. "Commercial Vehicle" and "Private Vehicle" should not be abstract, unless there are concrete subclasses of those two.
You may also not be understanding what your instructor means by "only one object", since that doesn't make sense.
Maybe you are to make one object which represents the DMV, but the definition of that object includes instances of other objects.
class DMV {
private List<Vehicle> vehicles = new List<Vehicle>();
...
}
Your instructor may want you to instantiate multiple objects through a reference to the abstract base class:
Vehicle conveyance;
conveyance = new PrivateVehcicle();
conveyance.Drive();
conveyance.Stop();
// or whatever ...
conveyance = new CommercialVehcicle();
conveyance.Drive();
conveyance.Stop();
i.e. you have a single object reference (conveyance) that behaves polymorphically depending on the concrete type you've instantiated.
Related
I am trying to understand the logic behind some C# casting conditions for classes, This is my testing code
File: example.cs
public class Animal { public string animal_name = "Animal"; }
public class Dog : Animal { public string dog_name = "Dog"; }
public class Class1
{
public void createObjects()
{
var animal1 = new Animal();
printAnimalName(animal1);
}
public void printAnimalName(Animal my_animal)
{
var dog1 = my_animal as Dog; // dog1 is of type Dog
Console.WriteLine(dog1.dog_name);
}
}
In my Main function, I call the call createObjects function as follows:
static void Main(string[] args)
{
Class1 c1 = new Class1();
c1.createObjects();
Console.ReadLine();
}
Running the code above gives an error
System.NullReferenceException:'Object reference not set to an instance of an object'
I understand that this is the way it should be, due to the casting in:
var dog1 = my_animal as Dog;
But what is the logic behind it? Why can't we call the function printAnimalName by passing an Animal object for it? This should be possible as per my understanding, because the function expects an Animal object.
After that var dog1 = my_animal as Dog; // dog1 is of type Dog you need to add only null check:
if(dog1 != null)
{
Console.WriteLine(dog1.dog_name);
}
I think you need to learn about polymorphism, abscract classes and interfaces.
public abstract class FourLeggedAnimal
{
public int GetLegCount()
{
return 4;
}
}
public class Dog : FourLeggedAnimal
{
public string GetScientificName()
{
return "doggus scientificus";
}
}
public class Cat : FourLeggedAnimal
{
public string GetServant()
{
return "human";
}
}
public class AnimalInformer
{
public void DisplayInformation(FourLeggedAnimal animal)
{
Console.WriteLine("It has {0} legs", animal.GetLegCount());
if (animal is Dog)
Console.WriteLine("Its scientific name is {0}", ((Dog)animal).GetScientificName());
if (animal is Cat)
Console.WriteLine("Its servant is {0}", ((Cat)animal).GetServant());
}
}
Here you use the absract class to provide base functionality to all other classes derived from it. All classes derived from FourLeggedAnimal have a method GetLegCount() that returns the number of legs.
But a cat has a servant a dog doesnt have, it just has a friend(both humans, but different relations). So the dog needs no method "GetServant" but the cat does. -> Differenct implementations in 2 seperate classes
Another example with interfaces is that each derived class needs to provide that functionality.
public interface IMovableObject
{
int GetMaxSpeed();
}
public class Car : IMovableObject
{
public int GetMaxSpeed()
{
return 100;
}
}
public class Human : IMovableObject
{
public int GetMaxSpeed()
{
return 20;
}
}
public static class SpeedChecker
{
public static void CheckSpeed(IMovableObject speedster)
{
Console.WriteLine("Checking Speed..");
int speed = speedster.GetMaxSpeed();
if (speed > 50)
Console.WriteLine("It's really fast!");
else
Console.WriteLine("Just a turtle or something similar...");
}
}
Now, if you have a Method getting a IMovableObject that is actually a car, you call the implementation of Car:
Car c = new Car();
Human h = new Human();
Console.WriteLine("Checking Car..");
SpeedChecker.CheckSpeed(c);
Console.WriteLine("Checking Human..");
SpeedChecker.CheckSpeed(h);
-> returns:
Checking Car...
Checking Speed...
It's really fast!
Checking Human...
Checking Speed...
Just a turtle or something similar...
These are 2 uses where you derive classes and use castings to get certain functionality or use the basetype without casting but still getting different functionality
Your problem is here:
public void printAnimalName(Animal my_animal)
{
var dog1 = my_animal as Dog; // dog1 is of type Dog
Console.WriteLine(dog1.dog_name); //Animal does not have this property!
}
Casting does not invoke a constructor. This means that dog_name is null, as my_animal does not have a dog_name property. I think you missed something on inheritance here.
This is actually an example that happens in more complex form in the real world; Given class A, B inherits from A. Both have the same properties because of inheritance. Then someone makes a different property with a similar, but not congruous property name and uses it for the same function in the child object. Welcome to code smell city.
To fix your function so it comes across as a dog, you'd do two things:
public class Animal { public string animal_name = "Animal"; }
//since we want a different default, we can
//can make the change in the constructor
public class Dog : Animal
{
Dog(){ this.animal_name = "Dog"; }
//if you really, really want a second name string, you can do this:
public string Dog_Name
{
get { return this.animal_name; }
set { this.animal_name = value; }
}
}
Then, you need to make your method call the appropriate property.
public void printAnimalName(Animal my_animal)
{
var dog1 = my_animal as Dog; // dog1 is of type Dog
Console.WriteLine(dog1.animal_name);
}
I also recommend changing your public fields to properties and possibly override ToString() when all you want to do with an object is return a string representing it.
Suppose I have these codes (and the classes are in the same namespace):
class Animal
{
int numberOfLegs = 4; // initialized
public int returnNumberOfLegs()
{
return numberOfLegs;
}
}
class Snake
{
internal Animal myAnimalObject = new Animal();
myAnimalObject.numberOfLegs = 0; // why is this line not allowed?
}
class Program
{
public static void Main(string [] args)
{
Snake mySnakeObject = new Snake();
Console.WriteLine("Snake");
Console.WriteLine("Number of Legs: {0}", mySnakeObject.myAnimalObject.returnNumberOfLegs());
}
}
Observe the class Snake. When I place these 2 lines of code in Main(), it is possible/allowed and will work if I declare the variable numberOfLegs with the right access modifier. Why can't I do it in the class Snake itself? What should I do to allow it?
Note that the 2nd line of code from class Snake is invalid and these are the errors it produced:
1) Error 1 Invalid token '=' in class, struct, or interface member declaration
2) Error 2 'myNamespaceName.Snake.myAnimalObject' is a 'field' but is used like a 'type'
Thanks. I just want to learn about this.
Edit:
Okay, thanks guys. I know about constructors and inheritance, but somehow, I'm being forced to do it "the hard and not-so-smart" way, for learning purposes(?). And that I even had to set the default value to 4. Thank you for your replies. Plus, I just made up these classes.
Because executable code should be placed either in constructor or in some method/property.
You cannot place code just inside the class, put it in the constructor.
class Snake
{
internal Animal myAnimalObject = new Animal();
public Snake()
{
myAnimalObject.numberOfLegs = 0;
}
}
When you write
internal Animal myAnimalObject = new Animal();
in the class body, it's a kind of a syntax sugar; compiler will create constructor and put your code line inside it.
and it will look like
class Snake
{
internal Animal myAnimalObject;
public Snake()
{
myAnimalObject = new Animal();
myAnimalObject.numberOfLegs = 0;
}
}
First of all, you can't do this in the class initializer:
myAnimalObject.numberOfLegs = 0;
Since you're not setting a class member itself, but rather interacting with a class member, you'd have to do it in the constructor:
public Snake()
{
myAnimalObject.numberOfLegs = 0;
}
Also, in order to access numberOfLegs it would need to be internal or public:
internal int numberOfLegs = 4; // initialized
More to the point of the whole scenario however, this seems like a very odd abstraction. Though part of me applauds the use of composition instead of inheritance, this seems more like a case where inheritance is warranted. It seems that Animal really shouldn't be initializing any value for numberOfLegs by default. Indeed, Animal shouldn't even be a concrete object given the real-world concepts being modeled. Instead, I might try something like:
abstract class Animal
{
public abstract int NumberOfLegs { get; }
}
class Snake : Animal
{
public override int NumberOfLegs { get { return 0; } }
}
The idea being that a Snake is an Animal, that an Animal by itself can't exist unless it's a specific type of Animal, and that each individual type of Animal internally controls its own values and all the abstract Animal class does is define what those values need to be.
You should use inheritance instead. Make Animal an abstract class, base class for all animals. Composition (what you use now) does not make much sense in this case.
abstract class Animal
{
protected int numberOfLegs = 4; // default number of legs
public int NumberOfLegs { get { return numberOfLegs; } }
public Animal(int legs)
{
numberOfLegs = legs; // initialize number of legs
}
}
All concrete animals then derive from this class.
class Snake : Animal
{
public Snake() : base(0) // specify that number of legs is 0
{
}
}
The base(0) is a call to a base class constructor, so you are calling Animal(int legs) with an argument 0.
Do it like this:
abstract class Animal
{
private readonly int numberOfLegs;
protected Animal(int nrLegs = 4)
{
numberOfLegs = nrLegs;
}
public int returnNumberOfLegs()
{
return numberOfLegs;
}
}
class Snake : Animal
{
public Snake() : base(0)
{
}
}
So I currently have an address book program (purposely basic as didn't fancy writing anything more fancy) so a module of an assessment being done (this is not school work).
I have to demonstrate polymorphism, encapsulation and inheritance in this module.
I was wondering if implementing IEnumerable counts as polymorphism as shown below?
public class AddressBookEnumerator : IEnumerator
{
#region IEnumerable Implementation
public Person[] Contacts;
int Position = -1;
public AddressBookEnumerator(Person[] ContactList)
{
Contacts = ContactList;
}
public bool MoveNext()
{
Position++;
return (Position < Contacts.Length);
}
public void Reset()
{
Position = -1;
}
object IEnumerator.Current
{
get
{
return Current;
}
}
public Person Current
{
get
{
try
{
return Contacts[Position];
}
catch (IndexOutOfRangeException)
{
throw new InvalidOperationException();
}
}
}
#endregion
}
I only wonder if it is because of inheriting the IEnumerator class and then creating new methods with different behaviour in for my specific class? Or am I just misunderstanding how IEnumerator works.
I'll try to break it down quickly,
interface IOrganism
{
string GetSpecies();
}
abstract class Animal : IOrganism
{
abstract string GetSpecies();
}
class Rat : Animal
{
public virtual string GetSpecies()
{
return "Ratus";
}
}
sealed class BlackRat : Rat
{
public override string GetSpecies()
{
return string.Format("{0} Ratus", base.GetSpecies()));
}
}
Animal, Rat and BlackRat are all polymorphic with IOrganism. Rat and BlackRat are polymorphic with Animal. Lastly, BlackRat is polymorphic with Rat.
This means, I can write a function,
void OutputSpecies(IOrganism organism)
{
Console.WriteLine(organism.GetSpecies());
}
It can accept any implementor of IOrganism, whether that be Rat, BlackRat or some future implementor, becuase they are all polymorphic with IOrganism.
So, to answer the original question, implementing an interface, like IEnumerable and using it as an argument to a function is using polymorphism. However, your code just implements IEnumerator, so is kind of half way there. It shows the potential for polymorphism but not polymorphism in practice.
Additionally, using IEnumerator as an example may distract from the desired task and you might be better to keep your example more abstract.
Polymorphism is a
a programming language feature that allows values of different data
types to be handled using a uniform interface.
In current code provided I see only one datatype you operate on.
Implementing IEnumerable is about subscribing to contract of a given interface, so your type can be threat like that interface. I, personally, would not dimonstrate this code like polymorphism example.
Whilst you can consider treating types at interface level as polymorphism, for the more academic approach, they are probably thinking more along these kind of lines?
Here we see:
Inheritance from the abstract base class Employee
Encapsulation / Polymorphism when we refer to the GetBonusMultiplier method. We are able to refer to the method from the abstract base class and we are also unaware of the internals of how each type determines the base multiplier. All we know / care is that when we call the method, we get an int value back.
If you wanted to change Employee to an interface IEmployee it would be simple. I would probably still have some kind of abstract base to capture the common fields though so you don't have to reimplement in each class that implements IEmployee.
class Program
{
static void Main(string[] args)
{
var employees = new List<Employee>
{
new Manager(1, "Dave Smith"),
new Director(2, "Peter Thompson")
};
foreach (Employee employee in employees)
{
Console.WriteLine(string.Format("Employee ID: {0}. Employee Name: {1}. Bonus Multiplier: {2}.", employee.Id, employee.Name, employee.GetBonusMultiplier()));
}
Console.ReadKey();
}
}
abstract class Employee
{
public int Id { get; protected set; }
public string Name { get; protected set; }
public abstract int GetBonusMultiplier();
}
class Director : Employee
{
public Director(int employeeId, string name)
{
Id = employeeId;
Name = name;
}
public override int GetBonusMultiplier()
{
return 3;
}
}
class Manager : Employee
{
public Manager(int employeeId, string name)
{
Id = employeeId;
Name = name;
}
public override int GetBonusMultiplier()
{
return 2;
}
}
I have a class for example Tile, with derive classes TileA, TileB... TileF.
Now I want always that class TileF changes with a call into TileE.
And also TileE to TileD, and you can see the patern.
Can I specify it directly in TileF where it changes into.
I'm looking at Activator.CreateInstance(), but this gives me a object class, and not the wanted derive class.
How can I solve this?
I do this in my Main loop, where I specified that Tile tile = TileF;
then i want to do something like: tile.change() and that it changes in a new TileE
Some kind of code:
Class Tile{
public abstract int Number{ get; }
}
Class TileF : Tile{
public override int Number
{
get
{
return 1;
}
}
}
Class TileE : Tile{
public override int Number
{
get
{
return 2;
}
}
}
Class Main{
Tile tile = new TileF;
//change tile to TileE
tile = tile.ToNextTileType();
}
When TileE and TileF are siblings, ie when they derive from a common baseclass, you cannot convert them directly.
There are several possible solutions but you don't provide much detail.
I think that maybe you should not use inheritance. Could a simple enum TileType solve your problem(s)?
You might want to look at interfaces. Interface lets unrelated objects be treated as the same thing when you reference a type of the Interface type e.g.
class ClassOne : ICommon;
class ClassTwo : ICommon;
class ClassThree : ICommon;
ClassOne x = new ClassOne();
ClassTwo y = new ClassTwo();
ClassThree z = new ClassThree();
List<ICommon> data = new List<ICommon>();
data.Add(x);
data.Add(y);
data.Add(z);
foreach(ICommon item in data)
{
item.InterfaceMethodOne();
}
This might not be what you want but it is worth looking into.
James :-)
There is a difference between the static and the dynamic type of an object. The static type of an object can be changed, that is you may write BaseType base = (BaseType)new DerivedType();. Changing the static type of an instance is called casting.
The compiler will restrict the call to methods, fields and properties present in the BaseType and all of its base types. The dynamic type of an object however may never change and in this case base still has the dynamic type DerivedType. The condition if (base is DerivedType) will return true in this case. You can only "change" the dynamic type by instantiating a new object of the target type and copy the desired values to the new instance. This process is called mapping.
Btw, Activator.CreateInstance will only give you an instance of the static type object, but likely with a different dynamic type. You can change the static type by casting it to a type that you know the object should have: (DerivedType)Activator.CreateInstance(typeof(DerivedType)). You can also use the generic variant, then this cast is done within the method: Activator.CreateInstance<DerivedType>(). Semantically there is no difference, except that the generic variant is easier to read.
EDIT:
Does this solve your problem?
public abstract class Tile {
public abstract int Number { get; }
public abstract Tile Advance();
}
public class TileA : Tile {
public override int Number { get { return 1; } }
public override Tile Advance() { return new TileB(); }
}
public class TileB : Tile {
public override int Number { get { return 2; } }
public override Tile Advance() { return new TileC(); }
}
public class TileC : Tile { ... }
You can also define the "state machine" in the abstract class like so:
public abstract class Tile {
public abstract int Number { get; }
public sealed Tile Advance() {
if (this is TileA) {
return new TileB();
else if (this is TileB) {
return new TileC();
}
}
}
Another alternative is of course to model the state machine entirely in one object:
public enum TileState { TileA, TileB, TileC };
public class Tile {
private TileState state = TileState.TileA; // initial state
public int Number {
get {
switch (state) {
case TileState.TileA: return 1;
case TileState.TileB: return 2;
...
default: return -1; // or throw exception
}
}
}
public void Advance() {
switch (state) {
case TileState.TileA: state = TileState.TileB; break;
case TileState.TileB: state = TileState.TileC; break;
...
default: // exception ?
}
}
}
In the last example, the behavior of your object changes depending on the state variable. It's not a new instance, but it can do something completely different. I hope something of this could help.
I made an error in designing TileF/TileE etc. It was good enough to make a TileN, with a property that is replacing the inner working of a tile. This way I don't have to substitute a class, and thus avoiding this problem.
(C#, VS2008) In a program I'm working on, I've got lots of objects that all have an ID and implement IComparable so that List<>-s of the various objects are easily searchable by ID. Since I hate copy/pasting code, I thought I'd abstract that bit of functionality down to a base class, like so:
using System;
namespace MyProg.Logic
{
abstract class IDObject : IComparable<IDObject>
{
private int miID;
public int ID
{
get { return miID; }
set { miID = value; }
}
public IDObject(int ID)
{
miID = ID;
}
#region IComparable<IDObject> Members
int IComparable<IDObject>.CompareTo(IDObject other)
{
return miID.CompareTo(other.miID);
}
#endregion
}
}
The drawback I see to that is that two separate classes that each inherit it would be directly comparable using .CompareTo() and I was hoping to enforce that each class that inherits from IDObject is only Comparable to others of the exact same class. So I was hoping to figure out how to do that and came up with this
using System;
namespace MyProg.Logic
{
abstract class IDObject : IComparable<T> where T : IDObject
{
private int miID;
public int ID
{
get { return miID; }
set { miID = value; }
}
public IDObject(int ID)
{
miID = ID;
}
#region IComparable<T> Members
int IComparable<T>.CompareTo(T other)
{
return miID.CompareTo(other.miID);
}
#endregion
}
}
But that gives a compile error of "Constraints are not allowed on non-generic declarations"
Looking at it, I'm sure there's a way to do something like that so that each class is only comparable to other instances of that same class, but I can't tease out the syntax.
You can use the Curiously Recurring Template Pattern to solve this problem.
abstract class Base<T> : IComparable<T> where T : Base<T> {
public int Rank { get; set; } // Order instances of derived type T by Rank
public int CompareTo(T other) { return Rank.CompareTo(other.Rank); }
}
class Foo : Base<Foo> {}
class Bar : Base<Bar> {}
static class Program {
static void Main() {
var foo1 = new Foo { Rank = 1 };
var foo2 = new Foo { Rank = 2 };
var bar1 = new Bar { Rank = 1 };
var bar2 = new Bar { Rank = 2 };
Console.WriteLine(foo1.CompareTo(foo2));
Console.WriteLine(bar2.CompareTo(bar1));
//error CS1503: Argument '1': cannot convert from 'Bar' to 'Foo'
//Console.WriteLine(foo1.CompareTo(bar1));
}
}
I think you've got bigger problems than just making sure that the derived class types are the same. You are also saddling the derived class with the responsibility to generate a unique ID. That requires the derived class to be aware what other IDs were assigned previously. Realistically, that requires a class factory. You'll need to enforce that by making the constructor of your abstract class protected.
Not very practical. If the ID is just an opaque number that establishes object identity then consider assigning the ID yourself. Use a static member to keep track of the last assigned one. Now it becomes simple, and you don't have to worry about derived class types anymore.