Computed properties vs methods with shape classes
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.