I've come across this recurring problem when trying to design the logic for my programs. Let's say I have a IDriveable interface.
interface IDriveable
{
public void Drive();
}
Then a car class that implements this (c#) syntax:
class Car : IDriveable
{
public void Drive(){
//Do the movement here.
}
}
Here's where my problem occurs. If I am designing a game, the car doesn't drive itself, a player should drive the car, surely that makes sense?
class player
{
public void Drive(IDriveable vehicle){
vehicle.Drive();
}
}
It feels like I am 'ping-ponging' the logic around which doesn't seem right.
A better way to structure your code might be something like this:
class Player // Start class names with a capital letter
{
Car thisPlayersCar; // Initialize it the constructor or somewhere appropriate
public void someFunction() {
thisPlayersCar.Drive();
}
}
Basically, the purpose of an interface is that wherever you call thisPlayersCar.Drive(); (or Drive() on any IDriveable), you're guaranteed that the object will have a Drive() function ready to go.
Related
I have an abstract class called Flight and its implement a interface called IFlight and it has a virtual method, another three classes that inherit from it, the only diffrence between those three classes is the implemantation of this method. Another thing that I want to do is implement a method that accepts as an argument an object of type IFlight (could be one of those three classes) and from them i want to access the members of the abstract class (Flight). Which way there is to implement such thing ?
Flight:
class AbsFlight: IFlight
{
public int ID { get; set; }
public string Start_Point { get; set; }
public virtual float Calculate_Price(float Base_Price)
{
return Base_Price;
}
}
One of the classes (The other two looks similar except the method "Calculate_Price"):
class Charter: AbsFlight
{
public override float Calculate_Price(float Base_Price)
{
return base.Calculate_Price(Base_Price) * 3;
}
}
Main:
private static void Some_Method(IFlight flight)
{
Console.WriteLine(flight.Calculate_Price(2)); //OK
Console.WriteLine(flight.ID); //Error
}
static void Main(string[] args)
{
List<IFlight> flights = new List<IFlight>();
flights.Add(new Regular());
flights.Add(new Charter());
flights.Add(new LowCost());
Main_SomeMethod(flights[0]);
}
Your current solution, in combination with some of the suggestions, will be a case of a mounted riding rider. You don't need an interface and a base class and testing for type.
You can solve your problem the way you're trying, with a base class and an interface. But it's overkill, and you have to kind of duplicate some stuff in the interface and the base class.
You can solve your problem with a simple base class and three derived classes where only Calculate_Price gets overridden. Put the common items in the base class. This is a very simple solution, easy to figure out, especially if C# and OOP is new to you.
You can also solve your problem with an interface and three classes, not derived. This has the disadvantage that you have to implement the interface in three classes. As Peter Csala points out, C# 8 has some language features that can help minimize this work, possibly making this just as simple as using only a base class and no interface. I am not too familiar with those features, so I can't judge whether it makes sense.
Then there is another option entirely. This touches on what zaitsman hinted at - that this is possibly an XY problem. Why do you want to distinguish between Regular, Charter and LowCost using classes derived from Flight/AbsFlight? Is it possible to just have an attribute that tells what price profile is used? Are there other fields and properties of a Flight that has nothing to do with the price, and yet also distinguishes flights? Perhaps just use one class.
About testing for class type. This is what we call code smell. Generally, if you test for class types a lot, then you defy the purpose of using classes and/or interfaces in the first place.
Your method should accept the type that has the properties it needs, in this case the AbsFlight class.
private static void Some_Method(AbsFlight flight)
{
Console.WriteLine(flight.Calculate_Price(2));
Console.WriteLine(flight.ID); //OK
}
But let's says the method must accept any IFlight. In this case, it can't be sure it received an AbsFlight; it has to check. After the check you can just cast.
private static void Some_Method(IFlight flight)
{
Console.WriteLine(flight.Calculate_Price(2));
if (flight is AbsFlight)
{
Console.WriteLine(((AbsFlight)flight).ID); //OK
}
}
With c#7 there is an additional construct you can use, if you think it is clearer:
private static void Some_Method(IFlight flight)
{
Console.WriteLine(flight.Calculate_Price(2));
switch (flight)
{
case AbsFlight absFlight:
Console.WriteLine(absFlight.ID); //OK
break;
}
}
It seems to be that you are doing something wrong that this is your requirement.
When you use an interface and pass it as an argument you want it to be common to all the objects that implement it.
Anyway, if you do want to do it. You might do something like:
if (flight is Flight)
{
Flight yourFlight = (Flight)flight;
// Here you can use anything you need from Flight, e.g: yourFlight.ID
}
I'm making my rpg game in unity. As I need a lot of different weapons, I tried to make a script for each weapons. Then instead of enacting the Attack function in each weapon's object, I wanted to controll them in other class such as WeaponManager for some reason.
However, I got no idea how to manage variety of classes. It doesn't seem efficient to write all the codes for each classes, such as
if((gameObject).name=="Wand")
gameObject.Getcomponent<Wand>().Attack();
else if((gameObject).name=="Sword")
gameObject.Getcomponent<Sword>().Attack();
... and so on.
In other way, I also thought of SendMessage function, but it doesn't seem like efficient as well.
I'm wodering how can I solve this problem. Which method can I use?
Classical example use case for object oriented programming:
Inheritance!
Use a shared parent class both inherit from and either implement the method virtual with a shared default behavior the inheriting classes can overwrite/extend or make it abstract so inheriting classes have to implement it.
public abstract class Weapon : MonoBehaviour
{
public abstract void Attack();
// alternatively implement some default behavior
// in this case the child classes can but don't have to override this
//public virtual void Attack()
//{
// Debug.Log("Harr Harr .. but I'll do nothing else!", this);
//}
}
and then
public class Wand : Weapon
{
public override void Attack()
{
...
}
}
and
public class Sword : Weapon
{
public override void Attack()
{
...
}
}
then simply go
gameObject.GetComponent<Weapon>().Attack();
I am coding an application that I thought would be a good chance to use a base class. I have Player class which holds an instance for each player on my game, I also have a PlayerManager class that has a dictionary of all the connected players, although I'll leave the PlayerManager class out of this question as this is just about the Player and PlayerData class.
So, I thought instead of having something like this, please note before checking this code snippet that I have removed a lot of the code and just shown a minimal example.
class Player
{
public PlayerData;
}
class PlayerData
{
public string Username;
public string Motto;
public string NickName;
}
class SomeOtherClass
{
public void Test()
{
var player = GetPlayer();
Console.WriteLine("Hello, I am " + player.PlayerData.Username);
}
}
I thought why have a method when I can have a base class? So I thought great, lets use a base class, this is what I ended up with.
internal class Player : PlayerData, IDisposable
{
private readonly Socket _socket;
private bool _disposeCalled;
private bool _receivingData;
private bool _hasAuthenticated;
public Player(Socket socket)
{
_socket = socket;
}
public void OnAuthenticated(MySqlDataReader reader)
{
if (_hasAuthenticated)
{
return;
}
_hasAuthenticated = true;
AssignData(reader);
}
public void Dispose()
{
if (_disposeCalled)
{
return;
}
_disposeCalled = true;
if (_receivingData)
{
_receivingData = false;
try
{
if (_socket != null && _socket.Connected)
{
_socket.Shutdown(SocketShutdown.Both);
_socket.Close();
}
}
catch
{
// ignored
}
_socket?.Dispose();
}
if (_hasAuthenticated)
{
SaveData();
}
}
}
internal class PlayerData
{
public int Id;
public string Username;
public void AssignData(MySqlDataReader reader)
{
while (reader.Read())
{
Id = reader.GetInt32("id");
Username = reader.GetString("username");
}
}
public void SaveData()
{
using (var dbConnection = Program.Server.Database.Connection)
{
dbConnection.SetQuery("UPDATE `users` SET `username` = #username WHERE `id` = #id");
dbConnection.AppendParameter("id", Id);
dbConnection.AppendParameter("username", Username);
dbConnection.ExecuteNonQuery();
}
}
}
You'll probably see the base class has a constructor, that's because I was going to just pass the PlayerData's data with the Player's constructor, but I wont actually get the data untill the Player's class has been fully initialized, I don't know when that will be as its done via socket packets, I just assign the data when I notice its been authenticated.
The point of my question is, should I use a base class like this, or should I not use a base class due to the fact I'm not initializing the data via the constructor, or is it okay to assign it via another method later on? Do I really need a base class, am I not following the right official rules for what a base class is and used for? Basically I just want to know, with this call stack should I be using a base class or method? I'm unsure on the rules.
So, the rules are not rules so much as guidelines (that not everyone really agrees on).
THAT SAID, I don't really see any benefit of lumping these classes together, although that could be because of so much of the code being removed.
In general, a good rule of thumb is not to use inheritance unless you have a good reason--a significant amount of code reuse that couldn't be achieved through composition, for example. In most cases, your code will be easier to maintain if you design with an eye for reducing dependencies (coupling), and the dependency between a subclass and its superclass is very strong. This means keeping things separate.
One technique you could do to simplify calls to player data is to "promote the interface"--basically, add the methods/properties you want as a sort of facade on the Player class, and have that relay the code to its PlayerData object. This has a few benefits:
1. It hides dependencies on PlayerData, which means you are free to change implementation to consolidate or use a different type (for example, if you just wanted to put those values in a data structure in the Player class)
2. It allows you to handle the case where PlayerData is being requested, but hasn't been initialized yet. For example, you could return default values or throw a custom exception.
3. Player and PlayerData are free to vary independently. So, if you run across a valid reason to subclass one or both of them, you won't be constrained.
In summary, it doesn't look like you really gain much from using inheritance in this way, but it would cut off design choices down the road. Also, anytime you are using inheritance to describe a relationship that is not an "IS A" relationship (PlayerData Is A Player? nope)--that smells fishy.
Again, guidelines. Bottom line is you want to design a system that you want to maintain, and design decisions come with trade-offs (often between simplicity and flexibility). So, if you decide there is a good reason to keep this as a subclass, just document it and don't worry about the OO Police coming after you for breaking the rules ;)
I don't think I explained my question very well in the title, so I'll do my best to do it here.
I have an abstract class called Song, a class that extends it MidiSongand then I have a SongCreator interface and a MidiSongCreatorclass that implements it. I would like to have a way to store lots of SongCreators so I can call their Create method but the problem is, since the SongCreators will each be a MidiSongCreator I am wondering how I should initialize each MidiSongCreator since it takes a MIDIPlayer and other things to help initialize it which doesn't have a static reference to it. Should I create a static class that holds lots of SongCreators? Should I not make the SongList class static?
What is looks like:
public abstract class Song{
public IList<Playable> notes { get; private set; }
public SongPlayData Start(){
// calls onStartEvent
return CreateSongData();
}
protected abstract SongPlayData CreateSongData();
public bool Update(SongPlayData songData, float songTime,List<SongPlayer> players) { // note that the players list is a list of people who are playing this game (this is a rhythm game) (doesn't have anything to do with MIDIPlayer
}
public void End(){
//calls end event
}
}
public class MidiSong : Song { // this is the class that needs the MIDIPlayer parameter
public MIDIPlayer midiPlayer;
protected MidiSong(MIDIPlayer player){
this.midiPlayer = player;
}
protected override SongPlayData CreateSongData() {
return new MidiSongData(midiPlayer);
}
}
public interface SongCreator<out T> where T : Song {
T Create();
}
public class MidiSongCreator : SongCreator<MidiSong>, IListenerObject { // this is the class that I need to store lots of instances of. the midiPlayer will probably be the same every time
private MIDIPlayer player;
public MidiSongCreator(MIDIPlayer player) {
this.player = player;
Init();
}
private void Init() {
player.midiListener.listener = this;
//
}
private void Clear() { // resets all the data so we can create another Song if we need to (even without entering stuff in)
if(player.midiListener.listener == this) {
player.midiListener.listener = null;
}
}
public MidiSong Create() {
MidiSong r = new MidiSong(player);
// I'm still going to implement calls to other methods from midiPlayer
Clear();
return r;
}
public void OnLoad(MidiFile file) {
// does stuff to load midi file (deals with individual events)
}
}
public class MasterSong : MonoBehaviour { // this should initialize last btw (It's in the Script Execution Order)
public MIDIPlayer midiPlayer;
public Song song;
public SongPlayData playData;
// Use this for initialization
void Start() {
// this is where I'd like to reference a SongCreator and call it's create method and Start the song
//for instance:
song = SongList.SONG_NAME.Create();
playData = song.Start();
}
void Update() {
}
}
It's a RhythmGame made with unity, but I didn't add the unity tag because I feel that this is more of a C#/design thing.
Also note, that I have my classes much more organized that just one file with all these.
I'm looking for ways to improve on the design that I have.
This is a design problem, domain design!
I suggest don't write code yet. Create a class diagram, with pen and paper, don't need to use tools in the beginning.
Try to determine entities - classes, interfaces etc - and the relationship among them. Just use boxes and arrow, don't need to put details yet. With boxes and arrows, you will be able to have a picture of your domain much more clearly. Keep refining and changing it, still at this high level, without details, until you are satisfied.
Then, step by step, refine it by adding details/properties such attributes and methods. This may cause to change the diagram from the first step.
I intentionally did not refer to specifics of you questions like the classes and interfaces you mentioned. Since, there is not enough information to comment on that. Secondly, and more importantly, you should start at high level of design and once that is done, then do coding based on your design.
Ok so I am making a game using XNA, I would like all of the enemies to extend from one base class called "baseEnemy.cs". For example, I would like a zombie to have a class called "zombie.cs" but make it entend the "baseEnemy.cs".
I think I remember being told its would be laid out like:
class zombie : baseEnemy
{
}
But I am assuming the use of get{} and set{} would help me to change values of current variables in zombies.cs that exist as part of baseEnemy.cs... If that makes sense? I don't understand the usage of get{} and set{} but I have seen it in other languages (such as the code for minecraft) which I would assume are similar in their working.
So, say I have a float for the speed of the enemy... I don't want all the enemies to move at the same speed (zombie's should have a low speed, etc). How could I get the speed from the baseEnemy.cs and set it as the speed in zombie.cs.
Or would I be better just making the variables public in baseEnemy.cs?
Sorry if the above doesn't make much sense, I am not too experienced with XNA or terminology used and therefore I probably sound like I am going round in circles :S
You are looking for so called abstract methods or abstract properties.
abstract class Enemy
{
public abstract float GetSpeed();
}
class Zombie : Enemy
{
public override float GetSpeed()
{
return 10;
}
}
Note the abstract keyword preceding the class name and the method name. The child class has to implement all abstract members, if it is not abstract itself. When an abstract member is implemented the override keyword must be used.
The get set syntax you are describing is called a property. It is a special C# construct that organizes the getter and/or setter of a field and puts them in a single block. The same example as above using properties:
abstract class Enemy
{
public abstract float Speed { get; }
}
class Zombie : Enemy
{
public override float Speed
{
get { return 10; }
}
}