[swift-evolution] [Draft] Allow declaration of abstract functions and properties on classes

Brent Royal-Gordon brent at architechies.com
Thu Feb 25 19:48:10 CST 2016


> That way would work if you forced every initializer in the class to accept a parameter representing each and every function you want to declare abstract. And it just gets messier from there, since if you wanted to do the same for get/set abstract properties, you'd need to model both the getter and setter separately, so for those you have 2 parameters.
> 
> If you have 2 abstract functions and 3 abstract get/set properties you want to model, you've just added 8 new parameters that you must pass to each one of your class's initializers.

Of course, which is why if you had eight override points, you would put them in one delegate protocol and pass in a single delegate instead. Your example had one override point, so it would be reasonable to use one closure, but even two override points would tilt the scales heavily towards using a delegate, and eight would be right out.

> It's one of the reasons we don't use Interface Builder with our Swift codebase. IB is an end-run around many of the compile-time safety features that make Swift great.


If you're not using IB, then there's no reason not to use a custom initializer that takes the delegate as a parameter, and you therefore would not need to worry about the delegate being uninitialized.

> Now that I think about it, what I'm talking about is pretty much the same behavior as the 'required' keyword with classes, but for things that aren't initializers.


The `required` keyword is something quite different—it states that all subtypes, at any degree of separation, must include this member. It only makes sense for initializers, because all other members are implicitly inherited and therefore subtypes always include them.

In other words, *all* members in Swift are required except for initializers without the `required` keyword, so the `required` keyword doesn't really make any sense here.

> The other problem with the protocol-based solution is that it leads to conceptual leakage. The protocol you need to declare lives outside the class(es) that need it.
> 
> The ActivityViewControlling protocol is now available universally, even though it's interface is only relevant to a certain portion the class hierarchy.

I'm not sure I understand what you mean, but I *think* you're complaining that you can apply ActivityViewControlling to something that's not a UIViewController. I do agree that's a problem, which is why I suggested we should allow protocols to require a particular superclass:

	protocol ActivityViewControlling: UIViewController {
		func retrieveText() -> String
	}
	extension ActivityViewControlling {
		...
	}
	class MyActivityViewController: ActivityViewControlling {
		func retrieveText() -> String { ... }
	}

The requirement would not constrain conforming types quite as tightly as an abstract class would—it would allow you to conform, say, a UITableViewController subclass to ActivityViewControlling. However, there are almost certainly cases where that would be a benefit, not a detriment, so that might be a net win even if it's not quite as good for this particular use case.

-- 
Brent Royal-Gordon
Architechies



More information about the swift-evolution mailing list