Computed properties vs methods with shape classes I'd be interested in hearing what folk think are the pros and cons of the following two ways of writing classes like the following Circle, Square and Rectangle classes in Swift.

The first way has them extending a superclass (ShapeSC) with methods. The second has them implementing a protocol (ShapeP) with computed properties. 
Both are tested with identical code, and give identical results.

Note: I've copied the code directly from a playground where it was working, so hopefully you'll find it error-free.

First way: subclasses extend a superclass and override "abstract" methods:

import UIKit
import Darwin

class ShapeSC {
   let π = M_PI
   var area: Double
   var perimeter: Double

   init() {
      area = 0
      perimeter = 0
   }

   func calcArea() -&gt; Double {
      return 0
   }

   func calcPerimeter() -&gt; Double {
      return 0
   }


class Circle: ShapeSC {
   var radius: Double

   init(radius: Double) {
      self.radius = radius
   }

   override func calcArea() -&gt; Double {
      return π * radius * radius
   }

   override func calcPerimeter() -&gt; Double {
      return π * 2 * radius
   }
}

class Square: ShapeSC {
   var side: Double

   init(side: Double) {
      self.side = side
   }

   override func calcArea() -&gt; Double {
      return side * side
   }

   override func calcPerimeter() -&gt; Double {
      return 4 * side
   }
}

class Rectangle: ShapeSC {
   var width: Double
   var height: Double

   init(width: Double, height: Double) {
      self.width = width
      self.height = height
   }


   override func calcArea() -&gt; Double {
      return width * height
   }

   override func calcPerimeter() -&gt; Double {
      return 2 * width + 2 * height
   }

}

let c1 = Circle(radius: 10)
c1.calcArea()
c1.calcPerimeter()

let s1 = Square(side: 10)
s1.calcArea()
s1.calcPerimeter()

let r1 = Rectangle(width: 5, height: 5)
r1.calcArea()
r1.calcPerimeter()


Second way: classes conform to a protocol and use computed properties:

import UIKit
import Darwin

protocol ShapeP {
   var area: Double { get }
   var perimeter: Double { get }
}

class Circle: ShapeP {
   let π = M_PI
   var radius: Double

   init(radius: Double) {
      self.radius = radius
   }

   var area: Double {
      return π * radius * radius
   }

   var perimeter: Double {
      return π * 2 * radius
   }
}

class Square: ShapeP {
   var side: Double

   init(side: Double) {
       self.side = side
   }

   var area: Double {
      return side * side
   }

   var perimeter: Double {
      return 4 * side
   }
}

class Rectangle: ShapeP {
   var height: Double
   var width: Double

   init(height: Double, width: Double) {
      self.height = height
      self.width = width
   }

   var area: Double {
      return width * height
   }

   var perimeter: Double {
      return 2 * width + 2 * height
   }
}

let c1 = Circle(radius: 10)
c1.area
c1.perimeter

let s1 = Square(side: 10)
s1.area
s1.perimeter

let r1 = Rectangle(height: 5, width: 5)
r1.area
r1.perimeter
Using a superclass

ShapeSC shouldn't be a superclass,
because it provides no useful implementation.
A shape with 0 area and perimeter doesn't make any sense.
Since there are no abstract classes in Swift,
ShapeSC cannot enforce sub-classes to override its methods.
So it's an outright dangerous approach,
as implementors may forget to replace the useless method with meaningful ones.

Btw, the π variable didn't belong in ShapeSC,
as it's only useful for Circle,
not by any other class in the hierarchy.

On the other hand,
it would have made sense to make Square extend Rectangle,
and inherit much of its implementation.

One small final note, I would write Rectangle's calcPerimeter method as:

   override func calcPerimeter() -&gt; Double {
      return 2 * (width + height)
   }


Using a protocol

If you notice,
writing it using a protocol automatically cleaned up some odd elements of the superclass variant: 


π is naturally defined in Circle, not somewhere else needlessly
No more 0-area 0-perimeter objects, by design


Even the code is shorter.
There are no obvious downsides either, which is in stark contrast with the superclass variant.

Using a mixed hierarchy

Consider a mixed hierarchy, using protocols and inheritance where they make sense.
For example Shape should clearly be a protocol,
but Rectangle can be a class that specialized cases like Square can inherit from.
As you explore the shape universe,
there might be other cases in the hierarchy where a protocol might make sense.