Vladimir
01/08/2025, 11:50 PMVladimir
01/08/2025, 11:52 PMinterface Movable {
fun move()
}
abstract class Animal {
abstract fun eat()
fun sleep() {
println("Zzz...")
}
}
class Dog : Animal(), Movable {
override fun move() {
println("Dog is walking")
}
override fun eat() {
println("Dog is eating")
}
}
Specifically, the class Dog
implementing both an Interface
and inheriting from an Abstract
class at the same time. Is this considered a good practice, particularly in the Android
ecosystem?
I have 2 repositories that implement 2 methods uniquely but share 1 identical method and this seems to be like a good solution?Vladimir
01/09/2025, 12:07 AMabstract
keyword redelegate and enforce its implementation details to its subclasses:
interface MusicPlayerRepository {
fun play()
fun search()
}
// Case 1: Base class implements the interface
abstract class BaseMusicPlayerRepository : MusicPlayerRepository {
// Must either:
// a) Implement all interface methods
override fun play() {
// Common implementation for playing audio
}
// b) Or mark them as abstract
abstract override fun search()
}
// Case 2: Classes inheriting from base class
class SpotifyRepositoryImpl : BaseMusicPlayerRepository() {
// Only needs to implement search() because play() is already
// implemented in the base class
override fun search() {
// Spotify-specific search using their API
}
}
class LocalFilesRepositoryImpl : BaseMusicPlayerRepository() {
// Only needs to implement search()
override fun search() {
// Local filesystem search
}
// Can optionally override play() if needed
override fun play() {
// Custom implementation for local files
}
}
Which of the approaches is considered more correct/ elegant?Vladimir
01/09/2025, 12:16 AM// Instead of inheritance:
abstract class BaseFileManager { ... }
class LocalFileManager : BaseFileManager()
// Prefer composition:
interface FileManager { ... }
class LocalFileManager(
private val commonFileLogic: CommonFileLogic
) : FileManager
Nestor Marsollier
01/09/2025, 12:30 AMNestor Marsollier
01/09/2025, 12:32 AM