Please consider this code :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
public class BaseClass
{
public virtual void DoWork() { Console.WriteLine("BaseClass\n"); }
public virtual int WorkProperty
{
get { return 0; }
}
}
public class DerivedClass : BaseClass
{
public override void DoWork() { Console.WriteLine("DerivedClass\n"); }
public override int WorkProperty
{
get { return 1; }
}
}
How can I use WorkProperty ? frankly it seems useless .
With the main :
class Program
{
static void Main(string[] args)
{
BaseClass A2 = new DerivedClass();
int a = A2.WorkProperty;
Console.WriteLine(a);
// do more stuff with `a`
}
}
On the other hand if I have something like this :
public class CoOrds
{
private int x, y;
public CoOrds() // constructor
{
x = 0;
y = 0;
}
public int X
{
get { return x; }
set { x = value; }
}
public int Y
{
get { return y; }
set { y = value; }
}
}
Then x and y are data members , and here the properties are helpful.
So what's the purpose of the property in the first code ?
Thanx
If you make your properties meaningful it makes more sense when you override them. A virtual property provides a default that child classes can override when it makes sense for them to override them. See this PsudoStream class example.
class PsudoStream
{
public virtual bool CanRead { get { return false; } }
public virtual bool CanWrite { get { return false; } }
}
class WritableStream : PsudoStream
{
//CanRead is false already and does not need to be overwritten
public override bool CanWrite { get { return true; } }
}
class ReadableStream : PsudoStream
{
//CanWrite is false already and does not need to be overwritten
public override bool CanRead { get { return true; } }
}
So what's the purpose of the property in the first code ?
The purpose of giving the WorkProperty in the baseClass is that it acts as default property if none of the derivedClass overrides the property.
for example consider this code,
public class BaseClass
{
public virtual void DoWork() { Console.WriteLine("BaseClass\n"); }
public virtual int WorkProperty
{
get { return 0; }
}
}
public class DerivedClass : BaseClass
{
public override void DoWork() { Console.WriteLine("DerivedClass\n"); }
}
class Program
{
static void Main(string[] args)
{
BaseClass A2 = new DerivedClass();
int a = A2.WorkProperty;
Console.WriteLine(a); ***//output will be "0"***
// do more stuff with `a`
}
}
Here the output is "0" because it used the Defauklt WorkProperty in the baseClass because there was no overridden implementation found.
Related
So I am reading that in .net it is not possible to inherit a second base class. How then Can you create an object that serves 2 functions from 2 classes? For example I have an object that I want to be a tool and a weapon. The first is public class SmithHammer : BaseTool the second would look like public class SmithHammer : BaseBashing The 2 classes BaseTool and BaseBashing can be used for the same item just not at the same time apparently. As a weapon I have it coded this way to call on the base class BaseBashing.
{
[FlipableAttribute( 0x13E3, 0x13E4 )]
public class SmithyHammer : BaseBashing
{
public override string Damage { get { return WeaponControl.Settings.SmithyHammerDamage; } }
public override int OldStrengthReq { get { return 45; } }
public override int OldMinDamage { get { return 6; } }
public override int OldMaxDamage { get { return 18; } }
public override int OldSpeed { get { return 40; } }
public override int InitMinHits { get { return 31; } }
public override int InitMaxHits { get { return 60; } }
[Constructable]
public SmithyHammer()
: base(0x13E3)
{
Weight = 8.0;
Layer = Layer.OneHanded;
Name = "Smith Hammer";
}
public SmithyHammer(Serial serial)
: base(serial)
{ }
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
}
}
}
And in the second use I have it as a tool
namespace Server.Items
{
[FlipableAttribute( 0x13E3, 0x13E4 )]
public class SmithHammer : BaseTool
{
public override CraftSystem CraftSystem{ get{ return DefBlacksmithy.CraftSystem; } }
[Constructable]
public SmithHammer() : base( 0x13E3 )
{
Weight = 8.0;
Layer = Layer.OneHanded;
}
[Constructable]
public SmithHammer( int uses ) : base( uses, 0x13E3 )
{
Weight = 8.0;
Layer = Layer.OneHanded;
}
public SmithHammer( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}
Is it not possible to make this item do both functions?
There is a mechanism for such scenarios - interfaces. Classes in C# does not support multiple inheritance but support implementing multiple interfaces. In this case you can create two interfaces (or even more) representing required contracts (i.e. interfaces):
public interface IBashing
{
string Damage { get; }
int OldStrengthReq { get; }
// ...
// rest of properties/methods for bashing/weapon
}
public interface ITool
{
CraftSystem CraftSystem { get; }
// ...
}
And implement them both the Hammer class:
public class SmithHammer : IBashing, ITool
{
public string Damage { get { return WeaponControl.Settings.SmithyHammerDamage; } }
public int OldStrengthReq { get { return 45; } }
public CraftSystem CraftSystem { get{ return DefBlacksmithy.CraftSystem; } }
// rest of implemetations
}
And clients can use this hammer class instance via interface or using type testing. For example if you introduce IItem interface to store everything in the inventory (i.e interface IBashing : IItem and interface ITool : IItem) it can look like this:
var inventory = new List<IItem>();
// add some items
// pick some i'th item:
var item = inventory[i];
var tool = item as ITool; // or use pattern matching here
if(tool != null)
{
// use tool
}
else
{
....
}
Sharing implementation is not that easy with interfaces (unless you can and want to use default interface implementations) but can be achieved via composition and wrapping, i.e.:
public class SmithyHammerBashing : BaseBashing
{
public override string Damage { get { return WeaponControl.Settings.SmithyHammerDamage; } }
public override int OldStrengthReq { get { return 45; } }
}
public class SmithHammer : IBashing, ITool
{
private readonly SmithyHammerBashing Bashing = new SmithyHammerBashing(); // or construct some other way
public string Damage { get { return Bashing.Damage; } }
public int OldStrengthReq { get { return Bashing.OldStrengthReq; } }
// the same approach for ITool
}
I try to simulate the decorator pattern in C#.
So I have these classes:
public abstract class Car
{
// private string description;
public abstract string Descripton
{
get;
}
public abstract int Cost();
}
public abstract class CarDecorator : Car
{
protected Car _decorated;
//private string description;
public CarDecorator(Car decoratied)
{
this._decorated = decoratied;
}
public override string Descripton
{
get
{
return _decorated.Descripton;
}
}
public override int Cost()
{
return _decorated.Cost();
}
public class EnhancedAutoPilot : CarDecorator
{
public EnhancedAutoPilot(Car car):base(car)
{
this._decorated = car;
}
public override string Descripton
{
get
{
return _decorated.Descripton + ", Enhanced autopilot";
}
}
public override int Cost()
{
return _decorated.Cost() + 5000;
}
}
public class ModelXS:Car
{
protected Car _decorated;
public string Description = "Model XS";
public override string Descripton
{
get
{
return _decorated.Descripton;
}
}
public override int Cost()
{
return 5500;
}
}
public class ModelXXX : Car
{
protected Car _decorated;
public string Description = "ModelXXX";
public override string Descripton
{
get
{
return _decorated.Descripton;
}
}
public override int Cost()
{
return 73000;
}
}
public class RearFacingSeats:CarDecorator
{
public RearFacingSeats(Car car):base(car)
{
this._decorated = car;
}
public override string Descripton
{
get
{
return _decorated.Descripton + ", Rear Facing Seats ";
}
}
public override int Cost()
{
return _decorated.Cost() + 4000;
}
}
public class SmartAirSuspension: CarDecorator
{
public SmartAirSuspension(Car car):base(car)
{
this._decorated = car;
}
public override string Descripton
{
get
{
return _decorated.Descripton + ", Smart Air Suspension ";
}
}
public override int Cost()
{
return _decorated.Cost() + 2500;
}
}
class Program
{
static void Main(string[] args)
{
Car car = new RearFacingSeats(new SmartAirSuspension(new EnhancedAutoPilot()));
}
}
But then I get this error:
There is no argument given that corresponds to the required formal parameter 'car' of 'EnhancedAutoPilot.EnhancedAutoPilot(Car)'
Your Cars are wrong, they look like decorators but are not, in fact they are supposed to be just implementations of Cars. Like this one:
public class ModelXS : Car
{
public override string Descripton
{
get
{
return "Model XS";
}
}
public override int Cost()
{
return 5500;
}
}
After that you can call the constructors like in #Richard 's answer and you are golden.
and you can ditch
public EnhancedAutoPilot(Car car):base(car)
{
this._decorated = car; // <<-- this lines
}
because you do that assignment in the base constructor of the CarDecorator class already.
You're using new EnhancedAutoPilot() constructor without parameters and it requires a Car parameter in your contructor signature.
public EnhancedAutoPilot(Car car):base(car)
Another issue i see is that you have _decorated in your Car class. The decorated object should only be in the Decorator classes.
So i would modify your car classes this way :
public class ModelXXX : Car
{
public override string Descripton => "ModelXXX";
public override int Cost()
{
return 73000;
}
}
public class ModelXS : Car
{
public override string Descripton => "Model XS";
public override int Cost()
{
return 5500;
}
}
And main would look like this :
static void Main(string[] args)
{
Car car = new ModelXXX();
car = new EnhancedAutoPilot(car);
car = new SmartAirSuspension(car);
car = new RearFacingSeats(car);
Console.Writeline(car.Descripton);
}
The error is telling you that you are not passing a value to the EnhancedAutoPilot() contstructor. All of your decorators require a Car instance be passed, thus you must instantiate a car first, before calling your decorators.
It looks like ModelXS and ModelXXX are types of cars, so the Program class should be:
class Program
{
static void Main(string[] args)
{
Car decoratedCar =
new RearFacingSeats(
new SmartAirSuspension(
new EnhancedAutoPilot(
new ModelXS())));
}
}
Ok, here we go !
I try to do a thing I never try before and... C# bit me.
The thing is my program need to translate some input objects to an output objects, with many in for one out at the time. And the out need the in for instantiate.
I'm not sure I'm very clear at this point... So an example to illustrate this will be better :
public class Class1
{
public interface ITranslatable { }
public interface ITranslatable<T> { }
public class OriginClass : ITranslatable { }
public class TargetClass : ITranslatable<OriginClass>
{
public TargetClass(OriginClass origin)
{
// Instantiate some properties from arg
}
}
public class Test
{
public Y Execute<X, Y>(X origin, Y target)
where X : ITranslatable
where Y : ITranslatable<X>, new()
{
target = new Y(origin); // <= How can I make this
// Some stuff
return target;
}
}
public TargetClass Function(OriginClass origin, TargetClass target)
{
var test = new Test();
return test.Execute(origin, target);
}
}
You declared new() constraint which mean that you expect class to have empy parameterless constuctor.
Does below code fits you needs?
public class Class1
{
public interface ITranslatable { }
public interface ITranslatable<T>
{
T Origin { get; set; }
}
public class OriginClass : ITranslatable
{
}
public class TargetClass : ITranslatable<OriginClass>
{
private OriginClass _origin;
public OriginClass Origin
{
get => _origin;
set
{
//Do some stuff
_origin = value;
}
}
public TargetClass()
{
}
}
public class Test
{
public Y Execute<X, Y>(X origin, Y target)
where X : ITranslatable
where Y : ITranslatable<X>, new()
{
var result = new Y {Origin = origin};
// Some stuff
return target;
}
}
public TargetClass Function(OriginClass origin, TargetClass target)
{
var test = new Test();
return test.Execute(origin, target);
}
}
After a few tries, I found the solution : use an abstract class.
Solution:
public class Class1
{
public interface ITranslatable { }
public interface ITranslatableOut
{
ITranslatable Origin { set; }
}
public class OriginClass : ITranslatable
{
public string Custom { get; set; }
}
public abstract class TargetBase : ITranslatableOut
{
public ITranslatable Origin { set { Initialize(value); } }
protected abstract void Initialize(ITranslatable input);
}
public class TargetClass : TargetBase
{
protected override void Initialize(ITranslatable input)
{
// Initialize some properties
}
}
public class Test
{
public Y Execute<X, Y>(X origin, Y target)
where X : ITranslatable
where Y : ITranslatableOut, new()
{
target = new Y { Origin = origin }; // It works !
// Some stuff
return target;
}
}
public TargetClass Function(OriginClass origin, TargetClass target)
{
var test = new Test();
return test.Execute(origin, target);
}
}
I have a abstract Class figures which contains Abstract properties
and I am Overriding them in Derived class Rectangle and
Square. Now, iI want to implement this with Interface. But I can't use
constructor and neither I can't Declare the Variable inside the
Interface. So, how to implement this using Interface where Figures Should be Interface and Square and Rectangle should be class?
abstract class Figures
{
int Width;
int _cs;
public Figures(int Width)
{
CS = Width;
}
public abstract int getarea
{
get;
}
public abstract int getperm
{
get;
}
public abstract int CS
{
set;
}
public abstract void display();
}
class Square : Figures
{
int _CsS;
public Square(int c) : base(c)
{
}
public override int getarea
{
get
{
return (_CsS * _CsS);
}
}
public override int getperm
{
get
{
return (2 * _CsS * _CsS);
}
}
public override int CS
{
set
{
_CsS = value;
}
}
public override void display()
{
Console.WriteLine("area={0} and perimeter={1}", getarea, getperm);
}
}
class Rectangle : Figures
{
int H;
int _csr;
public Rectangle(int H, int W) : base(W)
{
this.H = H;
}
public override int getarea
{
get
{
return H * _csr;
}
}
public override int getperm
{
get
{
return 2 * H * _csr;
}
}
public override int CS
{
set
{
_csr = value;
}
}
public override void display()
{
Console.WriteLine("area={0} and perimeter={1}", getarea, getperm);
}
}
so how to implement this using Interface
By definition, an interface won't let you implement anything. You can only specify things.
So you will have to remove the ctor and the fields from the interface IFigures and re-implement them in every class. You could reuse an implementation with a abstract class FiguresBase: IFigures but that's not always the best design.
It all depends on why you want the interface and how you will use it.
You can do something like this:
interface IFigures
{
int getarea
{
get;
}
int getperm
{
get;
}
int CS
{
set;
}
void display();
}
Thenk you can implement this interface from your classes and do your logic inside the class itself. So instead of putting the properties logic inside of your abstract class you will have to write them in your child classes.
class Square : IFigures
{
int _CsS;
public Square(int c)
{
CS = c;
}
public int getarea
{
get
{
return (_CsS * _CsS);
}
}
public int getperm
{
get
{
return (2 * _CsS * _CsS);
}
}
public int CS
{
set
{
_CsS = value;
}
}
public void display()
{
Console.WriteLine("area={0} and perimeter={1}", getarea, getperm);
}
//here you have implemented properties
}
Your abstract class is a good thing. It lets you re-use code.
Interfaces (i.e. contracts) are also good if you want to achieve a loosely coupled system.
You can use abstract classes and interfaces together, to achieve both code reusability and loosely coupled parts.
public interface IFigures
{
int getarea();
}
public abstract class Figures : IFigures
{
public abstract int getarea();
//opportunity for code reuse
protected int getarea_internal()
{
throw new NotimplementedExcpetion();
}
}
public class Square : Figures
public class Rectangle: Figures
here is the answer
with class Diagram
Class Diagram of the Program
interface IFigures
{
int Getarea
{
get;
}
int GetPerm
{
get;
}
int CS
{
//get;
set;
}
}
abstract class Figures:IFigures
{
int _Cs;
public Figures( int _Cs)
{
CS = _Cs;
}
public abstract int Getarea
{
get;
}
public abstract int GetPerm
{
get;
}
public abstract int CS
{
//get;
set;
}
public abstract void display();
}
class Circle:Figures
{
int _r, _csc;
public Circle(int _r):base(_r)
{
CS = _r;
}
public override int Getarea
{
get
{
return (_r * _r);
}
}
public override int GetPerm
{
get
{
return (2* _csc * _csc);
}
}
public override void display()
{
Console.WriteLine("area of Circle={0}", (_r * _r));
Console.WriteLine("perimeter of rectangle={0}", (2 * _r * _r));
}
public override int CS
{
//get
//{
// return _csc;
//}
set
{
_csc = value;
}
}
}
class Rectangle:Figures
{
int _L, _csr;
public Rectangle(int _L,int _W):base(_W)
{
this._L = _L;
CS = _W;
}
public override int Getarea
{
get
{
return _csr * _L;
}
}
public override int GetPerm
{
get
{
return (2* _csr * _L);
}
}
public override void display()
{
Console.WriteLine("area of rectangle={0}", (_csr * _L));
Console.WriteLine("perimeter of rectangle={0}", (2* _csr * _L));
}
public override int CS
{
//get
//{
// return _csr;
//}
set
{
_csr = value;
}
}
}
class Program
{
static void Main(string[] args)
{
Figures f = new Rectangle(3, 4);
f.display();
//f.CS = 5;
f.display();
Console.ReadKey();
}
}
is there a way to override a variable in a subclass, but also change the type to be a subclass of that type.
ie.
public class BaseClass
{
public BaseClass() { }
protected virtual MyBase WorkField { get { return new MyBase(); } }
public int WorkProperty
{
get { return WorkField.Value; }
}
}
public class DerivedClass : BaseClass
{
public DerivedClass():base() { }
/* I get an error here saying that WorkField needs to be MyBase type*/
protected override MyExtend WorkField
{
get
{
return new MyExtend();
}
}
//public new int WorkProperty
//{
// get { return 0; }
//}
}
public class MyBase
{
public int Value = 1;
}
public class MyExtend : MyBase
{
public int value = 20;
}
is there a way to do similar to this, but valid?
so i can have a superClass that does task on MyBase, and then have a subclass that does things on the MyEntend version of it.
without casting it everytime i use it.
There is no reason to change the signature in this case. Just return the derived type:
public class DerivedClass : BaseClass
{
public DerivedClass():base() { }
protected override MyBase WorkField
{
get
{
return new MyExtend();
}
}
//public new int WorkProperty
//{
// get { return 0; }
//}
}
The polymorphic behavior of your subclass will allow you to return it.
For overriding the signature should be of the base base method.
public class BaseClass<T> where T : MyBase, new()
{
public BaseClass() { }
protected virtual T WorkField { get { return new T(); } }
public int WorkProperty { get { return WorkField.Value; } }
}
public class DerivedClass : BaseClass<MyBase>
{
public DerivedClass() : base() { }
// same error occurs as base property is of type "MyBase"
protected override MyExtend WorkField { get { return new MyExtend();
} }
//public new int WorkProperty
//{
// get { return 0; }
//}
}
public class BaseClass<T> where T: MyBase, new()
{
public BaseClass() { }
protected virtual T WorkField { get { return new T(); } }
public int WorkProperty { get { return WorkField.Value; } }
}
public class DerivedClass : BaseClass<MyExtend>
{
public DerivedClass() : base() { }
protected override MyExtend WorkField { get { return new MyExtend(); } }
//public new int WorkProperty
//{
// get { return 0; }
//}
}
public class MyBase
{
public MyBase()
{
}
public int Value = 1;
}
public class MyExtend : MyBase
{
public int value = 20;
}