Explain Codes LogoExplain Codes Logo

Compare Protocol in Swift vs Interface in Java

swift
protocol-engineering
interface
multiple-inheritance
Anton ShumikhinbyAnton ShumikhinยทFeb 2, 2025
โšกTLDR

In both Swift and Java, Protocol and Interface are tools to enforce particular functionalities on classes. Swift's Protocol can contain both property declarations and default method implementations. Furthermore, structs and enums can also adopt protocols unlike in Java. On the other hand, Java's Interface is limited to method declarations; but, from Java 8, it started supporting default and static methods.

To get a quick grasp, here are some side-by-side examples:

// Swift protocols: Birds refusing to walk protocol Movable { func move() } extension Movable { func move() { print("๐Ÿฆ Bird: I'm not walking, I'm flying!") } } struct Bird: Movable {} Bird().move() // "๐Ÿฆ Bird: I'm not walking, I'm flying!"
// Java interfaces: Cars refusing to fly interface Movable { default void move() { System.out.println("๐Ÿš— Car: I'm not flying, I'm driving!"); } } class Car implements Movable {} new Car().move(); // "๐Ÿš— Car: I'm not flying, I'm driving!"

Both serve similar purposes but exhibit distinct language characteristics favoring reusability and consistency.

Decoding the fundamentals

Delving deeper, both protocol in Swift and interface in Java define contracts that typify a design pattern which can enforce consistency in software. But there are key differences:

The power of Swift protocols lies in their ability to define method signatures, property requirements, and type specifications. When it comes to state changes inside value types, don't forget Swift's mutating keyword.

On the other side, Java interfaces are the workaround for the language's lack of multiple inheritance feature allowing classes to implement multiple interfaces. Since Java 8, interfaces began to support default method implementations, increasing their capabilities.

Visualising the basics

Let's draw parallels to human professions:

**Swift's Protocol (๐Ÿ—๏ธ Architect):** Sets EXPECTATIONS and provides BLUEPRINTS of what features a struct, class or enum should have.
protocol Buildable { var door: Bool { get set } func construct() }
**Java's Interface (๐Ÿ”จ Blueprint):** Provide an OUTLINE of what tools and methods a class should implement.
interface Constructable { boolean hasDoor(); void build(); }

Both work as a blueprint, one being more detailed with implementation specifics (๐Ÿ—๏ธ) and the other being strictly an outline (๐Ÿ”จ).

Advanced Use Cases and Coding Patterns

When writing Swift code, protocol composition can be a sheer blessing as it gives you the ability to require an argument to adhere to multiple protocols:

// When you want an all-rounder builder who's fun to work with func findBuilder<T: Buildable & JokeCracker>(_ builder: T) { // Protocol composition FTW ๐Ÿš€ }

In the Java world, although such a fanciful feature doesn't exist, classes can indeed implement multiple interfaces. But be mindful, each method in such a class has to be explicitly implemented.

Avoiding Pitfalls and Finding Solutions

With all these features to enjoy, don't forget about the inevitable quirks. For instance, Swift Associated Types may limit the ability to use protocols as property types. To skirt this, you could use type erasure or leverage the power of generic classes.

Now, in Java, if a class gets too ambitious and tries to implement two interfaces with identical methods but different default implementations, you'll end up stuck with multiple inheritance issues. To avoid such a hassle, you'd need to override the method in the class and specify which interface's default method should be used.