Polymorphism - exercise - c#

Alright, so this is the exercise:
Define a class named student,
containing three grades of students.
The class will have a function that
calculates the grades average. Now,
define a class named student1 which
will be derived from student and will
add a function to calculate the sum of
the grades.In the Main program, define
a student variable and object of type
student1. Perform placement of the
object to variable and run the
function of student1.
Note: This is not homework, I'm learning this my own.
This is the code:
class Student
{
protected int grade1, grade2, grade3;
public Student(int grade1, int grade2, int grade3)
{
this.grade1 = grade1;
this.grade2 = grade2;
this.grade3 = grade3;
}
public double Average()
{
return (grade1 + grade2 + grade3) / 3;
}
}
class Student1 : Student
{
public Student1(int grade1, int grade2, int grade3)
: base(grade1, grade2, grade3)
{
}
public double Sum()
{
return grade1 + grade2 + grade3;
}
}
class Program
{
static void Main(string[] args)
{
}
}
I don't really know what to do in the main class, how do I perform this placement and also, I wanted to know what's the benefit of doing it, let me know if I have mistakes so far, thanks alot.

OK: I guess this is what they're looking for, although the english is a little ropey:
1) Declare student variable
Student s;
2) Declare Student1 object
Student1 s1 = new Student1(1,2,3);
3) Perform placement of object to variable:
s = s1;
4) Run the function (Note you'll have to cast s to Student1 type to access the Type specific function Sum)
Console.WriteLine(((Student1)s).Sum());

Maybe this is what it means.. although its really badly worded in my eyes.
In the Main program, define a student variable and object of type student1. Perform placement of the object to variable and run the function of student1.
static void Main(string[] args)
{
//define a student variable and object of type student1.
Student student = new Student1(100, 99, 98);
//Perform placement of the object to variable and run the function of student1
var sum = ((Student1)student ).Sum();
}

The primary flaw I see in your code from an OOP perspective is making Student1 extend from Student. When using inheritance, make sure it's a true extension (is a). You would be better served by making 1 student class and implementing the Sum and Average methods.
I think the following would be sufficient from an OOP perspective.
class Student
{
protected int grade1, grade2, grade3;
public Student(int grade1, int grade2, int grade3)
{
this.grade1 = grade1;
this.grade2 = grade2;
this.grade3 = grade3;
}
public double Average()
{
return (grade1 + grade2 + grade3) / 3;
}
public double Sum()
{
return grade1 + grade2 + grade3;
}
}

Following exactly what was described by the exercise:
// Define a student variable.
Student s;
// And object of type Student1.
Student1 s1 = new Student1(10, 5, 8);
// Perform placement of the object to variable.
s = s1;
// And run the function of Student1.
// But it makes no sense...
s1.Sum();
// Maybe the exercise wants it:
((Student1)s).Sum();
// Which makes no sense too, since is making an idiot cast.
// But for learning purposes, ok.
Well, I don't believe this exercise is taking any advantage of polymorphism in C#. I suggest you reading the link to see a real usage sample.

Related

C# properties and "tostring" method

I was trying to understand properties better and I came across this page with this example:
https://www.tutorialspoint.com/csharp/csharp_properties.htm
using System;
namespace tutorialspoint {
class Student {
private string code = "N.A";
private string name = "not known";
private int age = 0;
// Declare a Code property of type string:
public string Code {
get {
return code;
}
set {
code = value;
}
}
// Declare a Name property of type string:
public string Name {
get {
return name;
}
set {
name = value;
}
}
// Declare a Age property of type int:
public int Age {
get {
return age;
}
set {
age = value;
}
}
public override string ToString() {
return "Code = " + Code +", Name = " + Name + ", Age = " + Age;
}
}
class ExampleDemo {
public static void Main() {
// Create a new Student object:
Student s = new Student();
// Setting code, name and the age of the student
s.Code = "001";
s.Name = "Zara";
s.Age = 9;
Console.WriteLine("Student Info: {0}", s);
//let us increase age
s.Age += 1;
Console.WriteLine("Student Info: {0}", s);
Console.ReadKey();
}
}
}
output: Student Info: Code = 001, Name = Zara, Age = 9
I don't understand how the first example is able to output the whole line written in the class "student". In the main method, we are using "s" which is an object created in the class "exampledemo". How is it able to call a method from another class?
I guess it's something related to inheritance and polymorphism (I googled the override keyword) but it seems to me that the two classes are indipendent and not a subclass of the other.
I'm a total beginner at programming and probably quite confused.
s is of type Student (as declared on the first line of Main()). Therefore one can call a method on the object to modify it or print it. When you do s.Name = "Zara"; you are already calling a method on Student to update it (technically, a method and a property are the same, they only differ by syntax).
The line Console.WriteLine("Student Info: {0}", s); is actually the same as Console.WriteLine("Student Info: " + s.ToString());. The compiler allows writing this in a shorter form, but internally the same thing happens.
Let me show a real life example.
You have a sketch of your dream bicycle. Your bicycle exists only in sketch. This is a class.
Then you are going to garage and building your bicycle from the sketch. This process can be called like creation of object
of bicycle at factory from your sketch.
According to your example, class is Student.
You are creating an object by the following line:
Student s = new Student();
Object takes space in memory. How can we read values of objects from memory? By using object reference.
s is an object reference to the newly created object type of Student.
How is it able to call a method from another class?
s is an object reference to the newly created object type of Student. So it can call any public method of this object.
I was trying to understand properties
Properties are evolution of getter and setter methods. Looking for a short & simple example of getters/setters in C#
The compiler generates a pair of get and set methods for a property, plus a private backing field for an auto-implemented property.
Are C# properties actually Methods?

Not sure how to implement a Constructor and then call it via instance

Okay, so I have a couple of questions. Let me first explain what I have to do. I made this code first, but without the constructor and the two methods had static in their declaration. Now I want to add a constructor that I was provided and I have to make it's instance in the main method, and afterwards provide it with some random values. I also need to call the two methods via an instance in the Main method. At the end, after compiling, it's supposed to say "Hello World!" and "81" So here come the questions:
Are the variables in the constructor supposed to be the named the same as the ones in the methods?
How do I create an instance of the constructor in the main method?
How do I give it some random values?
How do I call the two methods via their instances?
The code:
namespace CalculatorA
{
class Calculator
{
public string WriteText(string parametar1)
{
return parametar1;
}
public int WriteNumber(int parametar2)
{
return parametar2;
}
public Calculator(int operand1, int operand2)
{
this.operand1 = operand1;
this.operand2 = operand2;
}
}
class Program
{
static void Main(string[] args)
{
string s = Calculator.WriteText("Hello World!");
Console.WriteLine(s);
string n = Calculator.WriteNumber(53 + 28).ToString();
Console.WriteLine(n);
Console.ReadLine();
}
}
}
I think you are lacking some object oriented programming concepts. Constructor is pretty much a method that initializes an instance of a class.
Are the variables in the constructor supposed to be the named the same
as the ones in the methods?
Constructor parameters have to be named. But there is no connection between constructor params and method params. These are just separate members of a class.
How do I create an instance of the constructor in the main method?
You create an instance of a class but not a constructor. Although construction is being called when you initiate an object using new keyword.
How do I give it some random values?
Depending on the type. For integer for example you can use new Random().Next().
How do I call the two methods via their instances?
I guess... just call... Just like that:
calc.Method1();
calc.Method2();
Question 1:
Yes and No - Yes because they can be named similarly or identically and still function because of their scope. No because in your example code you would want them to represent what values they'll be holding so you can, at a glance, understand their purpose. For simplicity, in the examples I display I will keep them as named in your example.
I suggest googling Scope and lifetime of Variables and Naming Conventions.
Also, it would be wise to apply either fields or properties to your Calculator class so the constructors values are stored for use by the methods within the class. Should this be your intent for the parameters.
Question 2:
Create an instance of the Calculator class
var calc = new Calculator(); //calc can be named to anything you want.
Question 3:
Using a instance of System.Random then producing a variety of random numbers like so.
var rnd = new Random();
var randomNumber1 = rnd.Next(0, 100);
var randomNumber2 = rnd.Next(0, 100);
//then using those in your Calculator.WriteNumber()
var calc = new Calculator(1,2); //without fields/properties this could be erroneous
var result = calc.WriteNumber(randomNumber1 + randomNumber2); //returns the sum of those to params.
Question 4:
You need to initialize an instance of the Calculator class - See Question 2. Then use that variable to access the methods eg:
var result = calc.WriteNumber(2); //returns 2
//or
var result = calc.WriteNumber(53 + 28); //returns 81
Here is some working code that you can learn from example. Hope this helps.
static void Main(string[] args)
{
//Create random numbers
var rnd = new Random();
var randomNumber1 = rnd.Next(1, 100); //get a random int between 1 and 99
var randomNumber2 = rnd.Next(1, 100); //and again
//Create instance of Calculator Class
var calc = new Calculator(randomNumber1, randomNumber2);
//Intro
string s = calc.WriteText("Hello World!");
Console.WriteLine(s);
//Do your addition method
var n = calc.WriteNumber(53 + 28);
Console.WriteLine(n);
//Do new addition method
var result = calc.Add(); //Returns _operand1 + _operand2
Console.WriteLine(result);
//exit application
Console.ReadLine();
}
class Calculator
{
// Set fields for your constructor to use.
// Another valid option is using properties, google this as its beyond the scope of a basic tutorial
private int _operand1, _operand2;
public string WriteText(string parametar1)
{
return parametar1;
}
public int WriteNumber(int parametar2)
{
return parametar2;
}
public int Add()
{
return _operand1 + _operand2;
}
public Calculator(int operand1, int operand2)
{
//You don't need the this keyword
_operand1 = operand1;
_operand2 = operand2;
}
}
The object's fields don't have to be the same as the constructor's parameters, although it is common for that to be the case.
var calculator = new Calculator(53,28);
Use the Random class
calculator.WriteNumber(53+28);
Are the variables in the constructor supposed to be the named the same as the ones in the methods?
The variables you have used in the constructor are not declared in the class.
your class should be like this:
class Calculator
{
private int operand1 {get; set;} //need to declare the var before using
private int operand2 {get; set;}
private string Message {get; set;}
public string WriteText() //you don't need to send parameters to the function if you have already got them in the contructor
{
return Message;
}
public int GetSum()
{
return operand1 + operand2;
}
public Calculator(string Message, int operand1, int operand2)
{
this.Message = Message;
this.operand1 = operand1;
this.operand2 = operand2;
}
}
class Program
{
static void Main(string[] args)
{
Calculator CalcObj = new Calculator ("Hello word!", 53, 28); //That is how you can initialize a class object
string s = Calculator.WriteText(); //this will return you the string you passed in controller
Console.WriteLine(s);
string n = Calculator.GetSum().ToString(); //that will give you sum of two operand
Console.WriteLine(n);
Console.ReadLine();
}
}
For random numbers you can use
Random() method in C# to generate random numbers in main method and pass them to the contructor of the class and GetSum will give you some of those numbers

Access object of a class from other classes

I realise this is probably a very simple question and will be answered in no time. But wondering what to do. I have a class called Budget with an object named 'user01' I would basically like to be able to access that object across multiple classes, similar to the code below.
Main
static void Main(string[] args)
{
Budget user01 = new Budget(1000);
}
Budget Class
class Budget
{
private int _budget;
public Budget(int budget)
{
_budget = budget;
}
public int UserBudget
{
get { return _budget; }
set { _budget = value; }
}
}
Expense Class
class Expenses
{
// What I've been trying to do...
public int Something(user01.budget)
{
user01.budget - 100;
return user01.budget;
}
}
I'm not really sure where to go from here, and am hoping to a little help/explanation. Many thanks
This is invalid:
public int Something(user01.budget)
But you can supply an instance of a Budget object to that method:
public int Something(Budget budget)
{
budget.UserBudget -= 100;
return budget.UserBudget;
}
Then you can invoke that method from your consuming code:
Budget user01 = new Budget(1000);
Expenses myExpenses = new Expenses();
int updatedBudget = myExpenses.Something(user01);
The method doesn't "access the variable user01". However, when you call the method, you supply it with your user01 instance. Inside of the method, the supplied instance in this case is referenced by the local budget variable. Any time you call the method and give it any instance of a Budget, for that one time that instance will be referenced by that local variable.
Go ahead and step through this using your debugger and you should get a much clearer picture of what's going on when you call a method.
(Note that your naming here is a bit unintuitive, which is probably adding to the confusion. Is your object a "budget" or is it a "user"? Clearly defining and naming your types and variables goes a long way to making code easier to write.)
Its a pretty simple change to your Expenses class:
class Expenses
{
// What I've been trying to do...
public int Something(Budget userBudget)
{
userBudget.UserBudget -= 100;
return userBudget.UserBudget;
}
}
Which you then call like this from your main class:
static void Main(string[] args)
{
Budget user01 = new Budget(1000);
Expenses expenses = new Expenses();
var result = expenses.Something(user01);
}
Or, if you make your Something method static you can call it without an instance:
class Expenses
{
// What I've been trying to do...
public static int Something(Budget userBudget)
{
userBudget.UserBudget -= 100;
return userBudget.UserBudget;
}
}
Which you call like this:
static void Main(string[] args)
{
Budget user01 = new Budget(1000);
var result = Expenses.Something(user01);
}
Its important when designing methods to remember that a method takes in a general argument and its the caller that passes in something specific.

What is the use of "this" in Java and/or C#? [duplicate]

This question already has answers here:
When do you use the "this" keyword? [closed]
(31 answers)
Closed 9 years ago.
Say I have a simple sample console program like below. My question is in regards to this. Is the sole use of this just so you can use the input variable name to assign to the instance variable? I was wondering what the use of this is other than used in the context of this program?
public class SimpleClass {
int numberOfStudents;
public SimpleClass(){
numberOfStudents = 0;
}
public void setStudent(int numberOfStudents){
this.numberOfStudents = numberOfStudents;
}
public void printStudents(){
System.out.println(numberOfStudents);
}
public static void main(String[] args) {
SimpleClass newRandom = new SimpleClass();
newRandom.setStudent(5);
newRandom.printStudents();
}
}
Previously, when I needed to assign a value to an instance variable name that shares similarities to the input value, I had to get creative with my naming scheme (or lack of). For example, the setStudent() method would look like this:
public void setStudent(int numberOfStudentsI){
numberOfStudents = numberOfStudentsI;
}
From that example above, it seems like using this replaces having to do that. Is that its intended use, or am I missing something?
Things are quite the opposite of how you perceive them at the moment: this is such an important and frequently used item in Java/C# that there are many special syntactical rules on where it is allowed to be assumed. These rules result in you actually seeing this written out quite rarely.
However, except for your example, there are many other cases where an explicit this cannot be avoided (Java):
referring to the enclosing instance from an inner class;
explicitly parameterizing a call to a generic method;
passing this as an argument to other methods;
returning this from a method (a regular occurrence with the Builder pattern);
assigning this to a variable;
... and more.
this is also used if you want to a reference to the object itself:
someMethod(this);
There is no alternative to this syntax (pun intended).
It's also used to call co-constructors, and for C# extension methods.
'this' simply refers to the object itself.
When the compilers looks for the value of 'numberOfStudents', it matches the 'closest' variable with this name. In this case the argument of the function.
But if you want to assign it to the class variable, you need to use the 'this.'-notation!
In the method
public void setStudent(int numberOfStudents){
this.numberOfStudents = numberOfStudents;
}
for example.
'this.numberOfStudents' references the class variable with the name 'numberOfStudents'
'numberOfStudents' references the argument of the method
So, this method simple assigns the value of the parameter to the class variable (with the same name).
in c# you use this to refer the current instance of the class object immagine you have class like this from msdn
class Employee
{
private string name;
private string alias;
private decimal salary = 3000.00m;
// Constructor:
public Employee(string name, string alias)
{
// Use this to qualify the fields, name and alias:
this.name = name;
this.alias = alias;
}
// Printing method:
public void printEmployee()
{
Console.WriteLine("Name: {0}\nAlias: {1}", name, alias);
// Passing the object to the CalcTax method by using this:
Console.WriteLine("Taxes: {0:C}", Tax.CalcTax(this));
}
public decimal Salary
{
get { return salary; }
}
}
class Tax
{
public static decimal CalcTax(Employee E)
{
return 0.08m * E.Salary;
}
}
class MainClass
{
static void Main()
{
// Create objects:
Employee E1 = new Employee("Mingda Pan", "mpan");
// Display results:
E1.printEmployee();
}
}
/*
Output:
Name: Mingda Pan
Alias: mpan
Taxes: $240.00
*/
You have different scopes of variables in Java/C#. Take this example below. Although this.numberOfStudents and numberOfStudents have the same name they are not identical.
public void setStudent(int numberOfStudents){
this.numberOfStudents = numberOfStudents;
}
this.numberOfStudents is a variable called numberOfStudents that is in the instance of this class. this always points on the current instance.
public void setStudent(int numberOfStudents) that numberOfStudents is a new variable that is just available in this method.
keyword "this" refers to an object of the current class (SimpleClass) on the fly.
public class SimpleClass(){
private int a;
private int b;
private int c;
public SimpleClass(int a, int b){
this.a = a;
this.b = b;
}
public SimpleClass(int a, int b, int c){
// this constrcutor
this(a,b);
this.c = c;
}
}

Virtual Method logic not working C# .NET 4.0

I'm working through an example in the bookPro C# and the .NET Platform and I'm making a mistake somewhere that I can't see. The program compiles and runs, but the Manager object in this example isn't having the right value of 'StockOptions' returned. In an effort of concision, I'm going to try to only post the relevant code because this example is all about class hierarchies and there's like six different classes. The virtual method GiveBonus in the Employee class isn't being correctly overridden in the Manager class.
class Manager : Employee
{
private int numberOfOpts;
//the properties are inherited from Employee
public int StockOptions { get; set; }
//***METHODS*** this is returns the StockOptions amount as it is in the
// constructor, there's no logic being applied
public override void GiveBonus(float amount)
{
base.GiveBonus(amount);
Random r = new Random();
numberOfOpts += r.Next(500);
}
public override void DisplayStats()
{
base.DisplayStats();
Console.WriteLine("you have {0} stock options", StockOptions);
}
public Manager() { }
public Manager(string fullName, int age, int empID, float currPay,
string ssn, int numbofOpts) : base(fullName, age, empID, currPay, ssn)
{
ID = empID;
Age = age;
Name = fullName;
Pay = currPay;
StockOptions = numbofOpts;
}
}
snippet from my Main() method
Manager chucky = new Manager("chucky", 50, 92, 100000, "333-33-3333", 9000);
chucky.GiveBonus(300);
chucky.DisplayStats();
Console.WriteLine();
I made a mistake while asking the question. What I should have asked is why I have to use
Console.WriteLine("you have {0} stock options", numbOfOpts);
instead of
Console.WriteLine("you have {0} stock options", StockOptions);
It's not meant to add a random number to 9000 - it's meant to give a random number of stock options as well as the "base" pay bonus:
public override void GiveBonus(float amount)
{
base.GiveBonus(amount);
Random r = new Random();
// Note numberOfOpts, not currPay
numberOfOpts += r.Next(500);
}
Unfortunately, as we've got two separate fields - one created by an automatically implemented property - it won't actually update the value of StockOptions... it's not clear whether this is due to your editing, or whether it's a mistake in the book. (There are various other things I dislike about this code, but hey...)

Categories