Inheriting fields from a base class C# - c#

I'm having trouble getting a class to inherit fields from its parent class.
I want the BullFrog class and Toad class to inherit all attributes from Amphibian class, and then overwrite the weight attribute. I thought it inherited all traits from the parent class by default, what am I missing here?
public class Animal
{
public string sound { get; set; }
public string move { get; set; }
public string favSnack { get; set; }
public double avgWeight { get; set; }
public void Speak(string sound)
{
Console.WriteLine( $"I go {sound}.");
}
public void Move(string move)
{
Console.WriteLine($"I {this.move} around the farm all day.");
}
public void Eat(string favSnack)
{
Console.WriteLine($"I like to eat {favSnack}.");
}
public void Weight(int avgWeight)
{
Console.WriteLine($"I usually weigh about {avgWeight}lbs.");
}
}
//decide on four or more animals
//for each animal decide on four or more methods
public class Amphibian : Animal
{
string sound = "ribbit";
string move = "hop";
string favSnack = "flies";
double avgWeight = .05d;
}
public class BullFrog : Amphibian
{
double avgWeight = .375d;
}
public class Toad : Amphibian
{
double avgWeight = .175d;
}
where did I go wrong? when I call the methods
BullFrog kermit = new BullFrog();
kermit.Move(kermit.movement);
kermit.Eat(kermit.favSnack);
I get "I around the farm all day" and two blank lines as the output.
My question is

Check the virtual and override keywords in C#. This is to be used in case you want to actually change the way the derived class moves. Go with the constructor way if it's just a string change.
public class Animal
{
public virtual string move { get; set; }
public class Amphibian : Animal
{
public override string move { get; set; } = "hop";
Your line string move = "hop"; is just declaring a private property inside the Amphibian class, which will not affect the base class in any way.
Another way to handle this would be to set the value in a constructor, but you should remember to always set the value in any constructor you are creating.
public class Animal
{
public string move { get; set; }
public Animal(string move) {
this.move = move;
}
And then
public class Amphibian : Animal
{
public Amphibian(): base("hop") {
}

Related

How access to abstract property from abstract that inherits interface?

I am not able to access a virtual property (IsNameAPalindrome) of an abstract class (PetBase ) having interface(IPet) inherited.
public interface IPet
{
string Name { get; set; }
}
public abstract class PetBase : IPet
{
public abstract string Name { get; set; }
public virtual bool IsNameAPalindrome
{
get
{
return (Name.Equals(string.Join("", Name.Reverse())));
}
}
}
The derived classes inherit the abstract class (PetBase)
public class Bird : PetBase
{
public override string Name { get; set; }
}
public class Cat : PetBase
{
public override string Name { get; set; }
}
public class Dog : PetBase
{
public override string Name { get; set; }
}
public class House : List<IPet>
{
}
Now when I try to access the property(IsNameAPalindrome) while looping through house object, it is not accessible
class Program
{
static void Main(string[] args)
{
House house = BuildHouse();
Print(house);
}
static void Print(House house)
{
// TODO: Print the contents of the house similar to the below.
// Feel free to change or improve upon the table as you see fit.
//Name Palindrome
//Gracie False
//Patches False
//Izzi True
//Missy False
Console.WriteLine("Name Palindrome");
foreach (var item in house)
{
Console.WriteLine( item.Name);
}
}
static House BuildHouse()
{
House house = new House();
house.Add(new Cat()
{
Name = "Gracie"
});
house.Add(new Cat()
{
Name = "Patches"
});
house.Add(new Bird()
{
Name = "Izzi"
});
house.Add(new Dog()
{
Name = "Missy"
});
return house;
}
}
You define House as List<IPet>, meaning the compiler will see each list element as the type IPet, which does not have a property IsNameAPalindrome.
If it makes logical sense for IsNameAPalindrome to be part of that interface contract, the simple solution is to add it:
public interface IPet
{
string Name { get; set; }
bool IsNameAPalindrome { get; }
}
If that does not make sense to you (and it may not, given that palendromes aren't closely linked to the concept of being a pet), you can:
Cast each IPet to PetBase to access that property
Implement a new interface e.g. IPalendrome, have PetBase also implement that interface, and cast to that interface to access the method.
Changes to the code for
First option
Console.WriteLine( ((PetBase)item).IsNameAPalindrome);
Second option
public interface IPalendrome
{
bool IsNameAPalindrome { get; }
}
public abstract class PetBase : IPet, IPalendrome
{
...
}
Console.WriteLine( ((IPalendrome)item).IsNameAPalindrome);

Extending classes with additional properties

I have an class object from an external library that I want to add some additional properties to.
Let's say the external class is:
public class ExternalClass
{
public string EXproperty1 {get;set;}
public string EXproperty2 {get;set;}
public string EXproperty3 {get;set;}
public ExternalClass(){}
}
and I have a list of these object which gets populated as
List<ExternalClass> listOfExternalClass=new List<ExternalClass>();
listOfExternalClass=GetListOfExternalClass();
I can extend this class by creating a new class, adding the additional properties and making the external class a property.
public class NewClass
{
public ExternalClass ExternalClass {get;set;}
public string NewProperty1 {get;set;}
public string NewProperty2 {get;set;}
public NewClass(){}
public NewClass(ExternalClass externalClass){
this.ExternalClass=externalClass;
}
}
But to convert by original list of the external classes to a list of the new classes I would have to create a new list of new classes and iterate through the original list creating a new object and adding it to the list, like
List<NewClass> listOfNewClass=new List<NewClass>();
foreach(var externalClass in listOfExternalClass)
{
listOfNewClass.Add(new NewClass(externalClass));
}
I would then be able to access the external properties like
listOfNewClass.FirstOrDefault().ExternalClass.EXproperty1;
Can I do this with inheritance or is there a more efficient method?
Ideally I would like to end up with by calling the properties like:
listOfNewClass.FirstOrDefault().EXproperty1;
This can certainly be done with inheritance. Consider the following.
//Inherit from our external class
public class NewClass: ExternalClass
{
//Note we do not have a copy of an ExternalClass object here.
//This class itself will now have all of its instance members.
public string NewProperty1 {get;set;}
public string NewProperty2 {get;set;}
//If it has parameters include those parameters in NewClass() and add them to base().
//This is important so we don't have to write all the properties ourself.
//In some cases it's even impossible to write to those properties making this approach mandatory.
public NewClass()
{
}
}
Few things to know:
Your code is called a wrapper. This is because it "wraps" another class or group of classes.
You cannot inherit from class marked as sealed.
In C# classes are not sealed by default. If they're sealed the developer has intentionally prevented you from inheriting from the class. This is usually for a good reason.
If you can actually extend the External class that would be easy to accomplish:
public class NewClass: ExternalClass
{
public string NewProperty1 {get;set;}
public string NewProperty2 {get;set;}
public NewClass(){}
public NewClass(ExternalClass externalClass){
// you would have to copy all the properties
this.EXproperty1 = externalClass.EXproperty1;
}
}
Yes inheritance is what you are looking for:
public class ExternalClass
{
public string EXproperty1 { get; set; }
public string EXproperty2 { get; set; }
public string EXproperty3 { get; set; }
public ExternalClass() { }
}
public class NewClass:ExternalClass
{
public string NewProperty1 { get; set; }
public string NewProperty2 { get; set; }
public NewClass() { }
}
If you wish for (or need) delegation instead of a copy you can do:
public class NewClass
{
public ExternalClass ExternalClass {get;set;}
public string NewProperty1 {get;set;}
public string NewProperty2 {get;set;}
public string EXproperty1 {get { return this.ExternalClass.EXproperty1; };set{ this.ExternalClass.EXproperty1 = value; }; }
public string EXproperty2 {get { return this.ExternalClass.EXproperty2; };set{ this.ExternalClass.EXproperty2 = value; }; }
public string EXproperty3 {get { return this.ExternalClass.EXproperty3; };set{ this.ExternalClass.EXproperty3 = value; }; }
public NewClass(){}
public NewClass(ExternalClass externalClass){
this.ExternalClass=externalClass;
}
}
Instead of working against specific types, work against interfaces.
Below I am showing a mix of facade pattern and adapter pattern to 'transform' external data to a well-defined interface (IDocument), effectively abstracting things your are working on.
Example 1 : query about an interface
Here are the types you'll work against:
public interface IDocument {
string Name { get; set; }
}
public interface IMetadata {
string[] Tags { get; set; }
}
This is your own representation, should you need any:
public class RichDocument : IDocument, IMetadata {
public string Name { get; set; }
public string[] Tags { get; set; }
}
This is the wrapper against external data:
(a bastard mix of facade and/or adapter concepts)
public class ExternalClass {
public string Whatever { get; set; }
}
public class ExternalDocument : IDocument /* only a basic object */ {
private readonly ExternalClass _class;
public ExternalDocument(ExternalClass #class) {
_class = #class;
}
public string Name {
get { return _class.Whatever; }
set { _class.Whatever = value; }
}
}
And a demo on how to use all that:
internal class Demo1 {
public Demo1() {
var documents = new List<IDocument> {
new ExternalDocument(new ExternalClass()),
new RichDocument()
};
foreach (var document in documents){
var name = document.Name;
Console.WriteLine(name);
// see if it implements some interface and do something with it
var metadata = document as IMetadata;
if (metadata != null) {
Console.WriteLine(metadata.Tags);
}
}
}
}
Example 2 : query about a component
This is a bit more involved by pushing the concept to treat everything in an uniform manner, you can find it in .NET framework, game development or whatever ...
Definitions you'll work against:
public interface IContainer {
IList<IComponent> Components { get; }
}
public interface IComponent {
// it can be/do anything
}
Some components you'll query about:
public interface IDocument : IComponent {
string Name { get; set; }
}
public interface IMetadata : IComponent {
string[] Tags { get; set; }
}
Your 'internal' type:
public class Container : IContainer {
public Container() {
Components = new List<IComponent>();
}
public IList<IComponent> Components { get; }
}
Your 'wrapper' against external data:
public class ExternalClass {
public string Whatever { get; set; }
}
public class ExternalContainer : IContainer {
private readonly List<IComponent> _components;
public ExternalContainer(ExternalClass #class) {
_components = new List<IComponent> {new ExternalDocument(#class)};
}
public IList<IComponent> Components {
get { return _components; }
}
}
public class ExternalDocument : IDocument {
private readonly ExternalClass _class;
public ExternalDocument(ExternalClass #class) {
_class = #class;
}
public string Name {
get { return _class.Whatever; }
set { _class.Whatever = value; }
}
}
And a usage example:
public class Demo2 {
public Demo2() {
var containers = new List<IContainer> {
new ExternalContainer(new ExternalClass()),
new Container()
};
foreach (var container in containers) {
// query container for some components
var components = container.Components;
var document = components.OfType<IDocument>().FirstOrDefault();
if (document != null) {
Console.WriteLine(document.Name);
}
var metadata = components.OfType<IMetadata>().FirstOrDefault();
if (metadata != null) {
Console.WriteLine(metadata.Tags);
}
}
}
}
Notes
The problem with inheritance is that it is a very rigid approach and generally once you start doing it and at some point you hit a wall and want to revert, it's hard to get out of it.
By working against abstractions things are more flexible and things are decoupled.
Here are two examples that might incite you to change your approach:
Composition over inheritance
Using Components

How to access the derived class properties from base class instance using generic method

I am trying to access all the properties of my derived class through base class reference variable.
Classes
public class vehicle
{
public int ID { get; set; }
}
public class Car : vehicle
{
public string type { get; set; }
public string Name { get; set; }
}
Here is the main in Main class
public static void saveCar<T>(T vehicle) where T : vehicle
{
//TODO : here I need to access all the propertie values but I dunno how access only derived class values
}
I am trying to do this way
static void Main(string[] args)
{
Car cr = new Car
{
ID = 1,
type = "car",
Name = "Maruthi"
};
saveCar<Car>(cr);
}
You can't really ask for T and know your real properties.
I think you should change your design to something like this:
public abstract class Vehicle
{
public int Id { get; set; }
public virtual void SaveCar()
{
// save Id
}
}
public class Car : Vehicle
{
public string Type { get; set; }
public string Name { get; set; }
public override void SaveCar()
{
base.SaveCar();
// Save type & name
}
}
Why do you have saveCar as a generic method? If the saveCar method is a virtual method on Vehicle you can override and have the required extended save functionality in each derived type.
However if you require an external method to handle actions such as save and have Vehicle and its derived classes as simple data representations, you will need to inspect the object and act accordingly. Some like:
public static void saveCar(Vehicle vehicle)
{
if (vehicle != null)
{
Console.WriteLine(vehicle.ID);
if (vehicle is Car)
{
var car = vehicle as Car;
Console.WriteLine(car.Name);
}
}
}

Using a base class as parameter

I'm sure this is just a matter of me not understanding something completely obvious, but I seem to be hopefully stuck on this.
I have an abstract base class that is inherited by a large amount of other classes, to maintain security information across my application. I'll simplify for this question though.
public abstract class ModelBase
{
public int UserID { get; set; }
public string UserName { get; set; }
}
public class SpecificModel : ModelBase
{
public int specificInt { get; set; }
public string specificString { get; set; }
}
In this case, about 30 different classes all inherit from ModelBase.
I would like to create a method that can accept any object who's class inherits from ModelBase. So I created something like this:
public bool TestIt (ref ModelBase BaseModel)
{
BaseModel.UserID = 10;
BaseModel.UserName = "Evan";
return true;
}
However, if I try to pass in an object of type SpecificModel, I get an error.
SpecificModel hiThere = new SpecificModel();
hiThere.specificInt = 5;
hiThere.specificString = "Oh well";
bool retVal = TestMethods.TestIt(ref hiThere);
The error I see on the last line is: The best overloaded method match for 'TestMethods.TestIt(ref ModelBase)' has some invalid arguments
What am I not "getting" here?
Thanks
You have it right, except you don't want to be passing by ref (likely the source of your error). Your class is already a reference type, you probably don't need to pass a reference to it. Given the function definition in the question;
public bool TestIt (ModelBase BaseModel)
{
BaseModel.UserID = 10;
BaseModel.UserName = "Evan";
return true;
}
Will be perfect (except for the weird "always return true" but perhaps thats because this is demo code).
whats the error it throwing?
I have tried it myself its nothing look wrong in your code. might be your calling mechanism is not correct. here is the sample code.
class Program
{
static void Main(string[] args)
{
ModelBase sp = new SpecificModel2();
TestIt(ref sp);
}
public static bool TestIt(ref ModelBase BaseModel)
{
BaseModel.UserID = 10;
BaseModel.UserName = "Evan";
return true;
}
}
public abstract class ModelBase
{
public int UserID { get; set; }
public string UserName { get; set; }
}
public class SpecificModel : ModelBase
{
public int specificInt { get; set; }
public string specificString { get; set; }
}
public class SpecificModel2 : ModelBase
{
public int specificInt { get; set; }
public string specificString { get; set; }
}
}

Do inheritance right

I have class:
internal class Stage
{
public long StageId { get; set; }
public string StageName { get; set; }
public int? Order { get; set; }
public Stage()
{
Order = 0;
}
}
I have also:
public class GroupStage : Stage
{
private override long StageId { set { StageId = value; } }
public GroupStage() : base() { }
public void InsertStage(long groupId)
{
}
public static void SetStageOrder(long stageId, int order)
{
....
}
public static void DeleteStage(long stageId)
{
....
}
public static GroupStage[] GetStages(long groupId)
{
....
}
}
and:
public class TaskStage : Stage
{
public DateTime? Time { get; set; }
public TaskStage()
: base()
{
....
}
public static Stage GetNextTaskStage(Guid companyId, long taskId)
{
....
}
public static Stage[] GetTaskStages(Guid companyId, long taskId)
{
....
}
}
This is not working and I get the exception:
Inconsistent accessibility: base class Stage is less accessible than class GroupStage
I want Stage class to be private and without access except to GroupStage and TaskStage. I also want to make StageId be private in GroupStage and in TaskStage.
How can I do that without duplicate the members of Stage in GroupStage and in TaskStage?
You can't make a derived class more accessible than it's base class. What you can do is make TaskStage and GroupStage internal as well, then inherit and expose public interfaces so that only the interface is visible outside of your assembly.
public interface IGroupStage
{
public string StageName{ get; set; }
...
}
interal class GroupStage : IGroupStage
{
...
}
You need to make you Stage class public or protected. if you make it abstract it cant be instantiated on that level, so if its public you dont have to worry about it being created as a base class
Make it protected instead of private. If you make it protected, you let classes that inherit from it call methods on the base class, and inherit the base class members.
What you probably actually want is for Stage to be an abstract base class which, therefore, cannot directly be instantiated regardless of its accessibility modifier. Change your definition of Stage:
public abstract class Stage
{
protected long StageId { get; set; }
public string StageName { get; set; }
public int? Order { get; set; }
protected Stage()
{
Order = 0;
}
}
The protected modifier means that your derived classes will be able to access that member, but it will not be accessible outside those classes.

Categories