[swift-evolution] [Review] SE-0026 Abstract classes and methods

Brent Royal-Gordon brent at architechies.com
Thu Mar 3 16:16:52 CST 2016


> Yes, a protocol will force you to provide an implementation. However, a protocol *by itself* cannot force the implementor of a class to provide an implementation unless that class declares itself in conformance with that protocol.
> 
> ONLY an abstract class, ON ITS OWN, can force concrete subclassers to provide an implementation for a given thing.
> 
> Protocols can't do this, because if you forget to declare conformance with the protocol, the compiler can't enforce anything. This pushes what could be caught at compile-time to a runtime (potentially crashing) problem.

If you forget to declare inheritance from an abstract class, it won't force you to implement those methods, either.

I do completely understand your concerns about the class + protocol workaround which is currently necessary here. That's why I'm proposing we allow protocols to require inheritance, override members, create stored properties, etc. That would allow the protocol to *wholly* replace the base class, taking on the job of providing both the concrete portions of the implementation and the requirements subtypes need to satisfy.

> Abstract classes enforce a requirement that a given portion of the class hierarchy provide an implementation of X.


Protocols don't operate entirely within the class hierarchy, but Swift's type system is broader than just a class hierarchy. In the context of the entire type (directed acyclic) graph, they play the same role of enforcing requirements on subtypes. And with the proper features in place, that's all we really need.

> Swift isn't ONLY about protocol oriented programming. Classes are here for a reason, and they should not be relegated to second-class status where people refuse to consider class-only functionality just because the concept can't be shoehorned into something protocol-related.

For what it's worth, even though I prefer the protocol solution in this case, I share your frustration with the reviews that do little more than recite "Protocol-Oriented Programming" as a slogan. I believe there are strong, convincing reasons to prefer the protocol approach here, but none of them are captured by that phrase.

But I think the pro-abstract class side is suffering from the same problem. Why is it so important that this feature be expressed strictly within the class hierarchy? Both extending classes to support abstract class-style functionality *and* extending protocols to support abstract class-style functionality bring abstract class-style functionality into the language. I'm not saying they're completely interchangeable and equivalent—there are differences, there are reasons to prefer one over the other—but they ultimately provide most of the same functionality.

If we went the abstract class route instead of the protocol route, I would be disappointed—I would think that we took the well-trodden path rather than explore something that was better and more consistent with the language. But I wouldn't feel like there was a gaping void in the language, because abstract classes *would* fulfill most of the use cases here.

I don't understand why you and the other abstract class supporters don't feel the same way—why you seem to treat this like a fight for your lives, not like a fight for the modestly superior design. The only thing that makes sense to me is dogmatism, but I want to give you more credit than that.

So explain to me: if this code worked:

	protocol ActivityViewControlling: UIViewController {
		func retrieveText() -> String
	}
	extension ActivityViewControlling {
		@IBOutlet var messageLabel: UILabel!
		
		override func viewWillAppear(animated: Bool) {
			super.viewWillAppear(animated)
			messageLabel.text = retrieveText()
		}
	}

What would you feel was missing compared to this?

	abstract class ActivityViewController: UIViewController {
		abstract func retrieveText() -> String
		
		@IBOutlet var messageLabel: UILabel!
		
		override func viewWillAppear(animated: Bool) {
			super.viewWillAppear(animated)
			messageLabel.text = retrieveText()
		}
	}

-- 
Brent Royal-Gordon
Architechies



More information about the swift-evolution mailing list