📖 Scenario: You are building a simple program to manage different types of notifications in a system. Each notification type should be able to send a message in its own way.
🎯 Goal: Create a Go program that defines an interface for sending notifications and implements this interface with two different notification types: Email and SMS. Then, use these implementations to send messages.
📋 What You'll Learn
Define an interface called Notifier with a method Send(message string)
Create a struct called Email with a field address string
Create a struct called SMS with a field number string
Implement the Send method for both Email and SMS to print a message showing where the notification is sent
Create variables of type Email and SMS with example data
Use the Notifier interface to call Send on both notification types
Print the output messages
💡 Why This Matters
🌍 Real World
Interfaces are used in real-world Go programs to write code that works with different types in a uniform way, such as sending notifications through email, SMS, or other channels without changing the main logic.
💼 Career
Understanding interfaces is essential for Go developers because many Go libraries and frameworks use interfaces to allow flexible and testable code.
Progress0 / 4 steps
1
Create the Email and SMS structs
Create a struct called Email with a field address string and a struct called SMS with a field number string.
Go
Hint
Use the type keyword to define structs with the specified fields.
2
Define the Notifier interface
Define an interface called Notifier with a method Send(message string).
Go
Hint
Interfaces in Go are defined using the type keyword followed by the interface name and the interface keyword.
3
Implement the Send method for Email and SMS
Implement the Send(message string) method for the Email struct that prints "Sending email to {address}: {message}" and for the SMS struct that prints "Sending SMS to {number}: {message}".
Go
Hint
Use receiver functions to implement the Send method for each struct. Use fmt.Printf to print the messages.
4
Create instances and send messages using the interface
Create a variable emailNotifier of type Email with address "user@example.com" and a variable smsNotifier of type SMS with number "123-456-7890". Then create a slice of Notifier called notifiers containing both variables. Use a for loop with variable notifier to call Send("Hello World") on each notifier. This should print the messages.
Go
Hint
Create instances of Email and SMS, put them in a slice of Notifier, and loop over them to call Send.
Practice
(1/5)
1. What does it mean for a type in Go to implement an interface?
easy
A. The type can only have one method.
B. The type inherits from the interface.
C. The type must be explicitly declared as implementing the interface.
D. The type has all the methods declared in the interface.
Solution
Step 1: Understand interface implementation in Go
In Go, a type implements an interface by having all the methods the interface declares.
Step 2: Compare options with Go's rules
Go does not use inheritance or explicit declarations for interfaces; it uses method sets.
Final Answer:
The type has all the methods declared in the interface. -> Option D
Quick Check:
Interface implementation = method set match [OK]
Hint: Check if all interface methods exist in the type [OK]
Common Mistakes:
Thinking Go uses inheritance for interfaces
Believing explicit declaration is needed
Confusing interfaces with structs
2. Which of the following is the correct way to declare that a type implements an interface in Go?
easy
A. type MyType struct implements MyInterface {}
B. type MyType struct { MyInterface }
C. No explicit declaration needed; implement all interface methods
D. func (m MyType) implements() MyInterface {}
Solution
Step 1: Recall Go interface implementation syntax
Go does not require explicit declarations; a type implements an interface by having all its methods.
Step 2: Analyze each option
Options A, B, and D show invalid or non-Go syntax; only C correctly states Go's implicit implementation.
Final Answer:
No explicit declaration needed; implement all interface methods -> Option C
Quick Check:
Implicit implementation = No explicit declaration needed; implement all interface methods [OK]
Hint: Remember: Go uses implicit interface implementation [OK]
Common Mistakes:
Trying to declare implementation explicitly
Using inheritance syntax from other languages
Adding interface as a struct field
3. What will be the output of the following Go code?
package main
import "fmt"
type Speaker interface {
Speak() string
}
type Dog struct {}
func (d Dog) Speak() string {
return "Woof!"
}
func saySomething(s Speaker) {
fmt.Println(s.Speak())
}
func main() {
var d Dog
saySomething(d)
}
medium
A. Woof!
B. Compilation error: Dog does not implement Speaker
C. Runtime error
D. No output
Solution
Step 1: Check if Dog implements Speaker
Dog has a method Speak() string, so it implements Speaker interface.
Step 2: Trace the function call saySomething(d)
saySomething calls s.Speak(), which returns "Woof!" and prints it.
Final Answer:
Woof! -> Option A
Quick Check:
Interface method call prints "Woof!" [OK]
Hint: Check if method signatures match interface exactly [OK]
Common Mistakes:
Assuming explicit declaration is needed
Confusing method receiver types
Expecting runtime errors without reason
4. Identify the error in this Go code that tries to implement an interface:
package main
import "fmt"
type Runner interface {
Run()
}
type Person struct {}
func (p *Person) Run() {
fmt.Println("Running")
}
func main() {
var r Runner
p := Person{}
r = p
r.Run()
}
medium
A. Missing Run() method in Person
B. Cannot assign Person value to Runner interface because Run() has pointer receiver
C. Interface Runner must have a return type
D. No error, code runs fine
Solution
Step 1: Check method receiver type
Run() is defined with pointer receiver (*Person), so only *Person implements Runner.
Step 2: Analyze assignment r = p
Variable p is a Person value, not *Person pointer, so it does not implement Runner.
Final Answer:
Cannot assign Person value to Runner interface because Run() has pointer receiver -> Option B
Quick Check:
Pointer receiver method requires pointer type [OK]
Hint: Match method receiver type with assigned variable type [OK]
Common Mistakes:
Ignoring pointer vs value receiver difference
Assuming interface methods must return values
Thinking interface assignment always works
5. Given these interfaces and types, which assignment is valid in Go?
type Reader interface {
Read() string
}
type Writer interface {
Write(string)
}
type ReadWriter interface {
Reader
Writer
}
type File struct {}
func (f *File) Read() string {
return "data"
}
func (f *File) Write(s string) {
// write data
}
func main() {
var rw ReadWriter
var f File
// Which assignment is valid?
}
hard
A. rw = &f
B. rw = f
C. rw = File{} (without methods)
D. rw = nil
Solution
Step 1: Check if File implements ReadWriter
File has Read() and Write(string) with pointer receivers (*File), so only *File implements ReadWriter; File value does not.
Step 2: Analyze assignment options
rw = &f is valid (&f is *File). rw = f fails (File doesn't implement). C invalid. rw = nil compiles but doesn't hold usable ReadWriter.
Final Answer:
rw = &f -> Option A
Quick Check:
Pointer receiver requires pointer type [OK]
Hint: Pointer receiver methods mean only pointer type implements interface [OK]
Common Mistakes:
Thinking value type implements pointer receiver interface
Assigning nil to interface without initialization
Confusing interface embedding with inheritance
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.