C# difference between member variables and arguments passed to a method - c#

I am working on an assignment with very specific instructions, which, if it is of any intrest, I will post below the code I have created. But, in short, I am to create a BasicShape abstract class, as well as a Circle and Rectangle subclasses. Each subclass has a method for calculating the area of the shape. the area is calculated using member variables. However, in my code below, these member variables are never assigned a value. I am confused as to how to assign it to them, because Circle and Rectangle methods also require arguments to be passed to them. These arguments x, y, r for Circle and w, l for Rectangle are specified in the main program when a new instance of a shape is made, but these values also seem to do nothing, since the output is always 0. What relationship do the arguments passed into the methods have to the member variables? How is it that the member variables should be assigned values when the values are given via arguments set when a Circle or Rectangle instance is called?
Here is my code:
abstract class BasicShape
{
protected double area;
public double getArea()
{
Console.WriteLine("Area: {0}", area);
return area;
}
public virtual void calcArea()
{
}
}
class Circle : BasicShape
{
private int centerX;
private int centerY;
private double radius;
public Circle(int x, int y, double r)
{
calcArea();
}
public int genCenterX()
{
return centerX;
}
public int genCenterY()
{
return centerY;
}
public override void calcArea()
{
area = 3.14159 * radius * radius;
Console.WriteLine("The area of the circle is: {0}", area);
}
}
class Rectangle : BasicShape
{
private int width;
private int length;
public Rectangle(int w, int l)
{
calcArea();
}
public int getWidth()
{
return width;
}
public int getLength()
{
return length;
}
public override void calcArea()
{
area = length * width;
Console.WriteLine("The area of the rectangle is: {0}", area);
}
}
public class TestShapes
{
static void Main(string[] args)
{
Circle circle1 = new Circle(2, 2, 5);
Rectangle rectangle = new Rectangle(6, 7);
Console.ReadLine();
}
}
Here are the instructions for the assignment:
Define a pure abstract base class called BasicShape.
The BasicShape class should have the following members:
Private Member Variable:
area, a double used to hold the shape’s area.
Public Member Methods:
getArea(): This method should return the value in the member variable area.
calcArea(): This method should be a pure virtual method.
Next, define a class named Circle. It should be derived from the BasicShape class. It should have the following members:
Private Member Variable:
centerX, an integer used to hold the x coordinate of the circle’s center.
centerY, an integer used to hold the y coordinate of the circle’s center.
radius, a double used to hold the circle’s radius.
Public Member Methods:
Circle(int x, int y, int r): accepts values for centerX, centerY, and radius. Should call the overridden calcArea
method described below.
genCenterX: returned the value in centerX
genCenterY: returned the value in centerY
calcArea(): calculates the area of the circle (area = 3.14159 * radius * radius) and stored the result in the inherited member area.
Next, define a class named Rectangle. It should be derived from the BasicShape class. It should have the following members:
Private Member Variable:
width, an integer used to hold the width of the rectangle
length, an integer used to hold the length of the rectangle
Public Member Methods:
Rectangle(int w, int l): accepts values for the width and length. Should call the overridden calcArea method described below.
getWidth(): returns the value in width.
getLength(): returns the value in length
calcArea(): calculates the area of the circle (area = length * width) and stored the result in the inherited member area.
After you have created these classes, create a main program that defined a Circle object and a Rectangle object.
Demonstrate that each object properly calculates and reports its area.

You don't assign the values passed from the constructor to your member variables. So when you call calcArea you execute it using the default values for the types int or double (which is zero)
class Circle : BasicShape
{
private int centerX;
private int centerY;
private double radius;
public Circle(int x, int y, double r)
{
radius = r;
// Now you are executing the calcArea using the value passed in
calcArea();
}
....
}
class Rectangle : BasicShape
{
private int width;
private int length;
public Rectangle(int w, int l)
{
width = w;
length = l;
calcArea();
}
....
}
The override of calcArea needs the member variables to be set to something otherwise these member variables are initialized with their default values (zero in both integer and double) and thus the method cannot produce a meaningful result.

Related

Why is are the result values are in 0 in C#?

I have this code and I am trying to calculate the area and circumference of the circle. I have tried debugging and I can see that the radius was passed but the area and circumference is not, it's always 0.
using System;
class Circle{
double radius;
double area;
double circumference;
public double Radius{set{radius = value;}}
public double Area{set{area=value;}}
public double Circumference{set{circumference=value;}}
public Circle(double radius){
this.radius = radius;
area=0;
circumference=0;
}
void CalculateArea(){
area=Math.PI*Math.Pow(radius,2);
}
void CalculateCircumference(){
circumference = 2*Math.PI*radius;
}
public void DisplayArea(){
System.Console.WriteLine("Area is {0}",area);
}
public void DisplayCircumference(){
System.Console.WriteLine("Circumference is {0}",circumference);
}
}
class TestCircle{
public static void Main(string[] args)
{
System.Console.WriteLine("Enter radius: ");
double radius=Convert.ToDouble(Console.ReadLine());
Circle theCircle = new Circle(radius);
theCircle.DisplayArea();
theCircle.DisplayCircumference();
}
}
this is the output
Enter radius:
3
Area is 0
Circumference is 0
You have a very strange design: set only Radius (once set I can't read it), editable (both get and set) Area: one
can easily assign -1.0 to it...
Let's redesign it; we have Circle class with three properties only:
class Circle{
// Radius, the man property we can
// - read it (get)
// - assign it, but let it be just once (so set is private)
public double Radius {get; private set;}
// Area, which we can just read (get, no set)
public double Area => Math.PI * Radius * Radius;
// Circumference, which we can just read (get, no set)
public double Circumference => 2 * Math.PI * Radius;
public Circle(double radius) {
Radius = radius;
}
public void DisplayArea(){
System.Console.WriteLine($"Area is {Area}");
}
public void DisplayCircumference(){
System.Console.WriteLine($"Circumference is {Circumference}");
}
}

List requires a type argument

There are three errors while compiling the code.
1.Using the generic type List requires 1 argument.
2.Using the generic type List requires 1 argument.
3. foreach statement cannot operate on variables of type because List does not contain a public definition for 'GetEnumerator'
The program of Polymorphism example is below.
namespace PolymorExample
{
abstract class Shape
{
public abstract void area();
}
class Rectangle : Shape
{
private double length;
private double width;
public Rectangle(double length, double width)
{
this.length = length;
this.width = width;
}
public override void area()
{
Console.WriteLine("Rectangel Area: {0}", length * width);
}
}
class Triangle : Shape
{
private double baseline;
private double height;
public Triangle(double baseline, double height)
{
this.baseline = baseline;
this.height = height;
}
public override void area()
{
Console.WriteLine("Triangel Area: {0}", baseline * height / 2.0);
}
}
class Circle : Shape
{
const double PI = 3.14;
private double radius;
public Circle(double radius)
{
this.radius = radius;
}
public override void area()
{
Console.WriteLine("Circle Area: {0}", radius * radius * PI);
}
}
public class TestShape
{
static void Main()
{
List shapes = new List();
Shape shape1 = new Rectangle(10, 10);
shapes.Add(shape1);
shapes.Add(new Circle(10));
shapes.Add(new Triangle(10, 10));
shapes.Add(new Circle(20));
foreach (Shape s in shapes)
{
s.area();
}
Console.Read();
}
}
}
If you take a look at the documentation for the List<T> class, you'll notice that List is a generic type (hence the <T>), and generic types require a parameter (or more) that specifies the type(s) of object it will use/contain. You must specify some type, even if it's just object.
In your case, you have a list of Shape objects, so your initialization code can be modified (and simplified by using collection initializer syntax) to specify that type:
var shapes = new List<Shape>
{
new Rectangle(10, 10),
new Circle(10),
new Triangle(10, 10),
new Circle(20)
};
List<Shape> shapes = new List<Shape>();
you need the shape type in your list declaration so it knows what its a list of

Calculate Surface Area of 2D shapes

A friend recently had a telephone interview and he was asked a technical question:
Q) If I wanted to calculate the surface area of some 2D shapes then what "Bucket" would I use. He had 20 minutes to write some code and the interviewer called him back. He sent the code via email and the code was not discussed for the remainder of the interview (there were no other technical questions). He sent me the code:
Windows Forms app
namespace ShapesApp
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.Load += form_load;
}
public void form_load (Object o, EventArgs e)
{
List<Shape> listShape = new List<Shape>();
Shapes.Circle circle = new Shapes.Circle();
Shapes.Rectangle rectangle = new Shapes.Rectangle();
Shapes.Square square = new Shapes.Square();
Shapes.Triangle triangle = new Shapes.Triangle();
listShape.Add(rectangle);
listShape.Add(square);
listShape.Add(triangle);
foreach (Shape shape in listShape)
{
double a = 10;
double b = 10;
double surfaceArea = shape.CalculateSurfaceArea(a,b);
Console.WriteLine("The surface area of a " + shape.GetType() + " is: " + surfaceArea);
}
}
}
}
Shapes - Class Library
namespace Shapes
{
public abstract class Shape
{
abstract public double CalculateSurfaceArea(double Double1, double Double2);
}
public class Circle : Shape
{
public override double CalculateSurfaceArea(double pi, double radius)
{
return (pi * radius) * (pi * radius);
}
}
public class Triangle : Shape
{
public override double CalculateSurfaceArea(double Base, double Height)
{
return (Base*Height)/2;
}
}
public class Rectangle : Shape
{
public override double CalculateSurfaceArea(double Length, double Width)
{
return Length * Width;
}
}
}
The interviewer has said that he "struggled" with the test. What is wrong with the code?
Calculating area is the behavior and every shape has his own formula for calculating it. Because calculating area can involve different amount of variables and constants method will not take any parameter and variables will be concern of class which implement interface .
So I think method of calculating area can be abstracted as interface:
public interface ICalculatingArea
{
double CalculateArea();
}
Then every shape will implement it on its own manner.
public class Rectangle:ICalculatingArea
{
public double Width {get; set;}
public double Length {get; set;}
public double CalculateArea()
{
return Length * Width;
}
}
In the main program it is enough to cast shape classes to the interface type and use CalculateArea method

What is happening when a Constructor uses 1 argument, but base keyword uses 2 arguments

I have this bit of code and it will demonstrate a Liskov substitution, but I'm confused what the base keyword is doing with 2 arguments. Can someone explain?
class Rectangle
{
public Rectangle(int width, int height)
{
Width = width;
Height = height;
}
public virtual int Height {get;set;}
public virtual int Width {get;set;}
public int Area
{
get { return Height*Width }
}
And now for the square class that inherits the base class with 2 arguments. I was also curious why this next Method Square(int) can use a method in the base class with a different name
private class Square : Rectangle
{
public Square(int size) : base(size, size) {} ///here is my confusion
public override int Width
{
get {return base.Width}
set { base.Width = value; base.Height = value}
}
public override int Height
{ /// same thing as Width }
}
base(size, size) calls the parent constructor ( Rectangle's in this case ), this constructor takes 2 arguments, that's why size is specified twice.
Because a square must have the same height and width the size parameter can be used for both width and height

Overriding properties doesn't work

My class Ellipse should inherit from my class Shape but I get this error message:
Error 1 'ConsoleApplication3.Ellipse' does not implement inherited abstract member 'ConsoleApplication3.Shape.Perimeter.get'
I also get the error message that I'm hiding Area, a property in Ellipse.
Can anyone help me please?
My shape class looks like this:
public abstract class Shape
{
//Protected constructor
protected Shape(double length, double width)
{
_length = length;
_width = width;
}
private double _length;
private double _width;
public abstract double Area
{
get;
}
And my ellipse class is:
class Ellipse : Shape
{
//Constructor
public Ellipse(double length, double width)
:base(length, width)
{
}
//Egenskaper
public override double Area
{
get
{
return Math.PI * Length * Width;
}
}
}
You need to use the override modifier on the Area and Perimeter properties in your Ellipse class, e.g.
public override double Area { get; }
public override double Perimeter { get; }
A tip for you in Visual Studio, put the cursor inside the text 'Shape' (in your ellipse class) and press Ctrl + .. This should add stubs for members you haven't implemented
May be this is what you after as you have not declared Length , Width any where in your Ellipse class so you might be getting compilation errors, to compile this you need enhance visibility of _length and _width properties of your base class Shape.
public abstract class Shape
{
//Protected konstruktor
protected Shape(double length, double width)
{
_length = length;
_width = width;
}
// have these variables protected since you instantiate you child through the parent class.
protected double _length;
protected double _width;
public abstract double Area
{
get;
}
}
class Ellipse : Shape
{
//Konstruktor
public Ellipse(double length, double width)
: base(length, width)
{
}
//Egenskaper
public override double Area
{
get
{
// use the variable inherited since you only call the base class constructor.
return Math.PI * _length * _width;
}
}
}

Categories

Resources