[SOLVED] How does Initialization and class inheritance of function work in Swift

Issue

Based on example from JavaScript code I would like to apply the same steps in Swift. If you can help me to understand how it can work to get area of all shapes.

enter image description here

Was trying to solve it with below code, however it does not work.

class Shape {
    func getArea() {
    }
}

class Square: Shape {
    var a: Double
    init(a: Double) {
        self.a = a
        super.init()
    }
    override func getArea() {
        a * a
    }
}

class Rectangle: Shape {
    var a: Double
    var b: Double
    init(a: Double, b: Double) {
        self.a = a
        self.b = b
        super.init()
    }
    override func getArea() {
        a * b
    }
}

class Circle: Shape {
    var r: Double
    init(r: Double) {
        self.r = r
        super.init()
    }
    override func getArea() {
        r * r * Double.pi
    }
}

let square = Square(a: 1.1)
let rectangle = Rectangle(a: 5.0, b: 9.1)
let circle = Circle(r: 2.3)
let shapes = [square, rectangle, circle]

func getTotalArea() -> Double {
    
    let areas = shapes.map { $0.getArea() }
    
    let sum = areas.reduce (1, +)
    
    return sum
}

let shapesArea = getTotalArea()
print(shapesArea)

Solution

getArea does not return anything. You have to define getArea() -> Double. Also Shape should be a protocol with func getArea() -> Double without implementation (without the braces).

Also note that when reducing (summing) areas, you have to start from 0, not from 1.

protocol Shape {
    func getArea() -> Double
}

class Square: Shape {
    var a: Double
    init(a: Double) {
        self.a = a
    }
    func getArea() -> Double {
        a * a
    }
}

class Rectangle: Shape {
    var a: Double
    var b: Double
    init(a: Double, b: Double) {
        self.a = a
        self.b = b
    }
    func getArea() -> Double {
        a * b
    }
}

class Circle: Shape {
    var r: Double
    init(r: Double) {
        self.r = r
    }
    func getArea() -> Double {
        r * r * Double.pi
    }
}

let square = Square(a: 1.1)
let rectangle = Rectangle(a: 5.0, b: 9.1)
let circle = Circle(r: 2.3)
let shapes: [Shape] = [square, rectangle, circle]

func getTotalArea() -> Double {

    let areas = shapes.map { $0.getArea() }

    let sum = areas.reduce(0, +)

    return sum
}

let shapesArea = getTotalArea()
print(shapesArea)

A more "Swifty" solution would be tu use structs, using their automatically generated inits, and area as a computed property:

protocol Shape {
    var area: Double { get }
}

struct Square: Shape {
    var a: Double
    var area: Double {
        a * a
    }
}

struct Rectangle: Shape {
    var a: Double
    var b: Double

    var area: Double {
        a * b
    }
}

struct Circle: Shape {
    var r: Double
    var area: Double {
        r * r * .pi
    }
}

let square = Square(a: 1.1)
let rectangle = Rectangle(a: 5.0, b: 9.1)
let circle = Circle(r: 2.3)
let shapes: [Shape] = [square, rectangle, circle]

func getTotalArea() -> Double {
    return shapes
       .map { $0.area }
       .reduce(0, +)
}

let shapesArea = getTotalArea()
print(shapesArea)

Answered By – Sulthan

Answer Checked By – Mary Flores (BugsFixing Volunteer)

Leave a Reply

Your email address will not be published.