📖 Scenario: You are building a simple system to handle different types of notifications in a company. Notifications can be sent via Email or SMS. Each notification type has its own way of sending messages, but your system should treat them the same way using an interface.
🎯 Goal: Create a Go program that uses an interface to send notifications through Email and SMS. You will define the interface, implement it with two types, and then use the interface to send messages.
📋 What You'll Learn
Create an interface called Notifier with a method Send(message string)
Create two structs called EmailNotifier and SMSNotifier
Implement the Send method for both EmailNotifier and SMSNotifier
Create a slice of Notifier containing both EmailNotifier and SMSNotifier
Use a for loop to call Send on each notifier with the message "Hello, team!"
Print the output of each Send call
💡 Why This Matters
🌍 Real World
Interfaces let you write flexible code that can work with different types of objects in a uniform way, like sending notifications through various channels.
💼 Career
Understanding interfaces is key for Go developers to build modular, testable, and maintainable software systems.
Progress0 / 4 steps
1
Define the Notifier interface and structs
Create an interface called Notifier with a method Send(message string). Then create two structs called EmailNotifier and SMSNotifier with no fields.
Go
Hint
Interfaces in Go are defined using the type keyword followed by the interface name and the methods inside curly braces.
2
Implement the Send method for both structs
Write the Send(message string) method for EmailNotifier that prints "Sending Email: " followed by the message. Also write the Send(message string) method for SMSNotifier that prints "Sending SMS: " followed by the message.
Go
Hint
Methods are defined with a receiver in parentheses before the method name. Use println to print the message.
3
Create a slice of Notifier and add instances
Create a variable called notifiers which is a slice of Notifier. Add one EmailNotifier and one SMSNotifier to this slice.
Go
Hint
Use a slice literal to create the slice with both struct instances inside curly braces.
4
Use a loop to send the message and print output
Add a main function if not present. Use a for loop with variable _, notifier to iterate over notifiers. Call notifier.Send("Hello, team!") inside the loop to send the message. This will print the output.
Go
Hint
The for loop iterates over the slice and calls the Send method on each notifier, printing the message.
Practice
(1/5)
1. What is the main purpose of an interface in Go?
easy
A. To define a set of method signatures that a type must implement
B. To store data values of different types
C. To create a new data type with fields
D. To perform arithmetic operations
Solution
Step 1: Understand what an interface represents
An interface in Go lists method signatures without implementations.
Step 2: Identify the role of interfaces
Any type that implements those methods satisfies the interface, enabling flexible code.
Final Answer:
To define a set of method signatures that a type must implement -> Option A
Quick Check:
Interface = method signatures [OK]
Hint: Interfaces list methods, not data or operations [OK]
Common Mistakes:
Confusing interfaces with structs
Thinking interfaces hold data
Assuming interfaces perform calculations
2. Which of the following is the correct way to declare an interface named Speaker with a method Speak() in Go?
easy
A. func Speaker() interface { Speak() }
B. interface Speaker { func Speak() }
C. type Speaker struct { Speak() }
D. type Speaker interface { Speak() }
Solution
Step 1: Recall Go interface syntax
Interfaces are declared with type Name interface { methods }.
Step 2: Match the correct syntax
type Speaker interface { Speak() } correctly declares Speaker as an interface with method Speak().
Final Answer:
type Speaker interface { Speak() } -> Option D
Quick Check:
Interface declaration = type Speaker interface { Speak() } [OK]
Hint: Use 'type Name interface { ... }' to declare interfaces [OK]
Common Mistakes:
Using 'interface' keyword alone without 'type'
Declaring interfaces as structs
Adding 'func' keyword inside interface methods
3. What will be the output of the following Go code?
package main
import "fmt"
type Speaker interface {
Speak()
}
type Dog struct {}
func (d Dog) Speak() {
fmt.Println("Woof!")
}
func saySomething(s Speaker) {
s.Speak()
}
func main() {
d := Dog{}
saySomething(d)
}
medium
A. Woof!
B. Compilation error
C. Runtime panic
D. No output
Solution
Step 1: Check if Dog implements Speaker
Dog has method Speak(), so it satisfies Speaker interface.
Step 2: Trace function call
In main, saySomething(d) calls d.Speak(), printing "Woof!".
Final Answer:
Woof! -> Option A
Quick Check:
Interface method call prints "Woof!" [OK]
Hint: Check if type has all interface methods to predict output [OK]
4. Identify the error in this Go code snippet using interfaces:
package main
import "fmt"
type Reader interface {
Read()
}
type File struct {}
func (f *File) Read() {
fmt.Println("Reading file")
}
func main() {
var r Reader
f := File{}
r = f
r.Read()
}
medium
A. Interface Reader cannot have methods
B. Method Read() must return a value
C. Cannot assign value of type File to Reader interface
D. No error, code runs fine
Solution
Step 1: Check method receiver type
Read() is defined on pointer receiver *File, not on File value.
Step 2: Understand interface assignment rules
Assigning f (value) to interface r fails because File does not implement Read(), only *File does.
Final Answer:
Cannot assign value of type File to Reader interface -> Option C
Quick Check:
Pointer receiver methods require pointer type assignment [OK]
Hint: Pointer receiver methods need pointer type to satisfy interfaces [OK]
Common Mistakes:
Ignoring pointer vs value receiver difference
Expecting interface to accept any type
Thinking methods must return values
5. Given these types and interfaces:
type Walker interface {
Walk()
}
type Runner interface {
Run()
}
type Athlete interface {
Walker
Runner
}
type Person struct {}
func (p Person) Walk() {
fmt.Println("Walking")
}
func (p Person) Run() {
fmt.Println("Running")
}
Which of the following statements is true?
hard
A. Person must explicitly declare it implements Athlete
B. Person implements Athlete because it has both Walk and Run methods
C. Athlete interface cannot embed other interfaces
D. Person only implements Walker, not Athlete
Solution
Step 1: Understand interface embedding
Athlete embeds Walker and Runner, so it requires both Walk() and Run() methods.
Step 2: Check Person methods
Person has both Walk() and Run() methods, so it satisfies Athlete interface automatically.
Final Answer:
Person implements Athlete because it has both Walk and Run methods -> Option B
Quick Check:
Interface embedding means combined methods [OK]
Hint: Embedded interfaces combine methods; implement all to satisfy [OK]
Common Mistakes:
Thinking explicit declaration is needed
Believing interface embedding is invalid
Assuming partial method implementation suffices
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.