Skip to content

Commit 0788b28

Browse files
committed
Adding solution to last exercise from Exam #2
1 parent 344c7fa commit 0788b28

5 files changed

Lines changed: 197 additions & 1 deletion

File tree

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
using System;
2+
3+
class Circle: Shape{
4+
// Radius property
5+
private int radius;
6+
public int Radius
7+
{
8+
get { return radius; }
9+
set
10+
{
11+
if (value < 0)
12+
throw new ArgumentException(
13+
"Radius must be strictly positive."
14+
);
15+
else
16+
radius = value;
17+
}
18+
}
19+
// Diameter property
20+
public int Diameter{get{return Radius * 2;}}
21+
22+
// Rest of the class
23+
public override double GetArea(){
24+
return Math.PI * Radius * Radius;
25+
}
26+
27+
public override string ToString(){
28+
return base.ToString() + $" a circle.\nRadius: {Radius}\nDiameter: {Diameter}.\n";
29+
30+
}
31+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
using System;
2+
3+
class Program
4+
{
5+
static void Main()
6+
{
7+
Circle test = new Circle();
8+
test.Radius = 6;
9+
Console.WriteLine(test);
10+
11+
Rectangle test0 = new Rectangle();
12+
test0.Width = 12;
13+
test0.Length = 10;
14+
Console.Write(test0);
15+
16+
Rectangle test1 = new Rectangle();
17+
test1.Width = 10;
18+
test1.Length = 12;
19+
Console.Write(test1);
20+
21+
Console.WriteLine("The two rectangles are identical (up to rotation): " + test1.Equals(test0));
22+
23+
Rectangle test2 = new Rectangle();
24+
test2.Width = 8;
25+
test2.Length = 12;
26+
Console.Write(test2);
27+
Console.WriteLine("The two rectangles are identical (up to rotation): " + test2.Equals(test0));
28+
}
29+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
using System;
2+
3+
public class Rectangle : Shape
4+
{
5+
private int width;
6+
public int Width
7+
{
8+
get { return width; }
9+
set
10+
{
11+
if (value < 0)
12+
throw new ArgumentException(
13+
"Width must be strictly positive."
14+
);
15+
else
16+
width = value;
17+
}
18+
}
19+
private int length;
20+
public int Length
21+
{
22+
get { return length; }
23+
set
24+
{
25+
if (value < 0)
26+
throw new ArgumentException(
27+
"Length must be strictly positive."
28+
);
29+
else
30+
length = value;
31+
}
32+
}
33+
34+
public override double GetArea(){
35+
return Width * Length;
36+
}
37+
38+
// ToString method
39+
public override string ToString()
40+
{
41+
return base.ToString() + " a rectangle (W:" + Width + ", L:" + Length + ", Area: " + GetArea() + ")\n";
42+
}
43+
44+
// Equals method
45+
public bool Equals(Rectangle rP){
46+
return (rP.Length == Length && rP.Width == Width) || (rP.Length == Width && rP.Width == Length);
47+
}
48+
// End of Equals method
49+
50+
51+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
public abstract class Shape
2+
{
3+
public abstract double GetArea();
4+
public override string ToString(){
5+
return "This shape is ";
6+
}
7+
}

source/solutions/oop/inheritance.md

Lines changed: 79 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,6 @@ tags:
181181
!include`snippetStart="// ToString method",snippetEnd="// End of ToString method"` code/projects/RoomBedBath/RoomBedBath/BathRoom.cs
182182
```
183183
</details>
184-
185184

186185
#. Consider the diagram representing the "Article", "Book" classes and their relations.
187186

@@ -221,3 +220,82 @@ tags:
221220
```
222221
</details>
223222

223+
#. Consider the diagram representing the "Shape", "Circle" and "Rectangle" classes, as well as their relations.
224+
225+
!include diag/cla/Shapes.md
226+
227+
#. Write the complete implementation of the `Shape` abstract class. The `ToString` method should simply return the string `"This shape is "`.
228+
229+
<details><summary>Solution</summary>
230+
```{download="code/projects/Shapes.zip"}
231+
!include code/projects/Shapes/Shapes/Shape.cs
232+
```
233+
</details>
234+
235+
#. Write an implementation for the `Radius` property of the `Circle` class such that setting the radius to a negative value would result in an `ArgumentOutOfRangeException` (that you can shorten to `AOORE`) exception being thrown. Add an attribute if needed.
236+
237+
<details><summary>Solution</summary>
238+
```{download="code/projects/Shapes.zip"}
239+
!include`snippetStart="// Radius property",snippetEnd="// Diameter property"` code/projects/Shapes/Shapes/Circle.cs
240+
```
241+
</details>
242+
243+
#. Write the `Diameter` property for the `Circle` class, which should return $2$ times the radius. Only the `get` should be provided: briefly explain why the `set` is missing.
244+
245+
<details><summary>Solution</summary>
246+
```{download="code/projects/Shapes.zip"}
247+
!include`snippetStart="// Diameter property",snippetEnd="// Rest of the class"` code/projects/Shapes/Shapes/Circle.cs
248+
```
249+
</details>
250+
251+
#. Write an implementation for the `ToString` method of the `Rectangle` class that returns a `string` containing what was returned by the `Shape`'s `ToString` method, the width, length and area of the calling object. For example, for a `Rectangle` with width 10 and length 5, it should be of the form "This shape is a rectangle (W: 10, L: 5, Area: 50)".
252+
253+
<details><summary>Solution</summary>
254+
```{download="code/projects/Shapes.zip"}
255+
!include`snippetStart="// ToString method",snippetEnd="// Equals method"` code/projects/Shapes/Shapes/Rectangle.cs
256+
```
257+
</details>
258+
259+
#. Write the `Equals` method for the `Rectangle` class. It should return `true` if the calling object and the parameter have the same lengths and same widths, or if one can be obtained by rotating the other.
260+
261+
<details><summary>Solution</summary>
262+
```{download="code/projects/Shapes.zip"}
263+
!include`snippetStart="// Equals method",snippetEnd="// End of Equals method"` code/projects/Shapes/Shapes/Rectangle.cs
264+
```
265+
</details>
266+
267+
#. Briefly explain how `Shape` could be converted into an interface and what would be the benefit(s) and disadvantage(s) of carrying out such a modification.
268+
269+
<details><summary>Solution</summary>
270+
A `Shape` interface would be
271+
272+
- less code,
273+
- without the need to explicitly list the methods as `public` and `abstract`,
274+
- not capable of specifying what the beginning of the string returned by the `ToString` method should be, or to give any non-abstract method for that matter.
275+
276+
Another benefit is that the `Rectangle` and `Circle` classes could realize multiple interfaces instead of only inheriting from the `Shape` class.
277+
278+
Its implementation would be:
279+
280+
```
281+
interface Shape
282+
{
283+
double GetArea();
284+
}
285+
```
286+
287+
Note that our interface *cannot* have a `ToString` method, for a delicate reason that we explain now, but that was not supposed to be part of the answer. You cannot force the implementation of a `ToString` with an interface, as discussed for example [in this stack exchange post](https://stackoverflow.com/q/510341), where an alternative solution is provided (essentially: use an abstract class).
288+
289+
You can convince yourself that this is the case by downloading and compiling the following two files:
290+
291+
```{download="code/projects/IToString.zip"}
292+
!include code/projects/IToString/IToString/IToString.cs
293+
```
294+
295+
```{download="code/projects/IToString.zip"}
296+
!include code/projects/IToString/IToString/Demo.cs
297+
```
298+
299+
This code would indeed compile just fine, *even if `Demo` does not provide the implementation of a `ToString` method*.
300+
Of course, `Demo` already posses a `ToString` method, the one every class inherits.
301+
</details>

0 commit comments

Comments
 (0)