Last active
February 1, 2017 16:42
-
-
Save mphuff/05a410e6d619eb81f227facd001b38ca to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace AnimalKingdom | |
{ | |
// I'm sticking a bit more with pseudo-code than FORMAL c-sharp (I'm a bit rusty there) | |
// More worth understanding some of the key concepts I would look for as an interviewer here: | |
// 1) Inheritance - check - you've got the idea of this in the bag | |
// 2) Encapsulation - you don't necessarily want just anybody to be able to take your object and modify properties about it | |
// - By setting the setters to private, utilizing them in a constructor (or other private-to-Animal method), you encapsulate any logic | |
// that may accompany that. Imagine having some logic in Animal base where, given a size and weight, you perform validation on that | |
// pair of data. If just anybody is able to modify the members, you wouldn't necessarily force validation. Yes, C# makes it a bit | |
// simpler with their get/set built-ins but it's best practice overall not to depend on the public get; set; methodology given that | |
// it doesn't translate to 'best oop' practice of encapsulation very well. | |
// 3) Abstraction - | |
// 4) Polymorphism - check - achieved at runtime through your use of inheritance | |
// TIP: Don't try to get too formal with 'generics' - it would definitely get in the way at an interview. Generics | |
// are a fantastic tool (e.g. <T>...) but not in simple OOP exercises. I've stripped them out of here for the purposes | |
// of simplicity in what I'm trying to convey with respect to the question at large. | |
// Keeping it at Animal is good enough - the vast majority of programming languages don't support generics. | |
public abstract class Animal | |
{ | |
// I would argue you should have a base constructor instead of a Produce method which doesn't | |
// explicitly state what is effectively required to make a new Animal: | |
protected Animal(double size, double weight) { | |
this.AnimalSize = size; | |
this.AnimalWeight = weight; | |
} | |
//'double' type here used for simplicity would rather use convertable unit types | |
public double AnimalSize {get; private set;} //eg cubic inches | |
public double AnimalWeight{get; private set;} //eg pounds | |
} | |
// Making both Animal and EggLayer abstract prevents somebody from actually instantiating them. | |
// However, you code can pass them around as if they are a thing (Polymorphism) that can be operated on. | |
// They're not super interesting objects but nonetheless serve the purpose at hand. | |
public abstract class EggLayer:Animal, ILaysEggs | |
{ | |
protected EggLayer(double size, double weight) : base(size, weight) { | |
// Other constructor logic for EggLayer? | |
} | |
public Egg LayEgg() | |
{ | |
return new Egg(); | |
} | |
} | |
// Similar to above, Bird now is probably an OK class to actually instantiate a new one of (if you don't know the type). | |
// Changing everything to Public here will allow you to do so obviously. But now you can cast Bird to an EggLayer OR | |
// an Animal as your needs require. | |
public class Bird: EggLayer, ICanFly | |
{ | |
public Bird(double wingSpan, double size, double weight) : base(size, weight) { | |
this.WingSpan = wingSpan; | |
} | |
public Fly() | |
{ | |
//Go places | |
} | |
public abstract double WingSpan {get; private set;} | |
} | |
public class Sparrow: Bird<Sparrow>, ICarnivore, IHerbavore | |
{ | |
//unique sparrow functionality | |
public Sparrow() | |
{ | |
AnimalSize = | |
Prey[] = new Animal[]{Worm}; //Worm is a simple animal type can be defined if needed | |
WingSpan = 1; | |
} | |
public bool TryHunt() | |
{ | |
//Do a hunt function using Prey property probably within an Area/Habitat type object | |
} | |
public bool TryScavenge() | |
{ | |
//Look for seeds etc, | |
} | |
//Add 'TryConsume' for | |
public void Consume(Animal prey) | |
{ | |
//Could extract this function... | |
bool isValid = false; | |
for(i=0,i < Prey[].Count, i++) | |
{ | |
if(Prey[i] == prey) | |
{ | |
isValid = true; | |
break; | |
} | |
} | |
if(!isValid) | |
throw; | |
//Do Removal of 'prey' etc | |
} | |
} | |
public class Egg<T>: Animal<Egg<T>> //T extends Animal I don't know the notation in C#? looks like it's 'where T: Animal' | |
{ | |
public Egg() | |
{ | |
Child = new T(); | |
} | |
private T Child{get;set;} | |
public Animal Produce() | |
{ | |
return Hatch(); | |
} | |
private T Hatch() | |
{ | |
return Child; | |
} | |
} | |
//Interfaces | |
public interface ICarnivore //Predator | |
{ | |
Animal[] Prey{get;set;} | |
bool TryHunt(); | |
void Consume(Animal prey); | |
} | |
public interface IHerbavore | |
{ | |
//Try to find/eat something that isn't an animal | |
bool TryScavenge(); | |
} | |
public interface ICanFly | |
{ | |
//Again Double used for simplicity | |
double WingSpan{get;set;} | |
void Fly(); | |
} | |
public interface ILaysEggs | |
{ | |
Egg LayEgg(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment