Skillsbench python-scala-oop
Guide for translating Python classes, inheritance, and object-oriented patterns to Scala. Use when converting Python code with classes, dataclasses, abstract classes, inheritance, properties, static methods, class methods, or design patterns.
install
source · Clone the upstream repo
git clone https://github.com/benchflow-ai/skillsbench
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/benchflow-ai/skillsbench "$T" && mkdir -p ~/.claude/skills && cp -r "$T/tasks/python-scala-translation/environment/skills/python-scala-oop" ~/.claude/skills/benchflow-ai-skillsbench-python-scala-oop && rm -rf "$T"
manifest:
tasks/python-scala-translation/environment/skills/python-scala-oop/SKILL.mdsource content
Python to Scala OOP Translation
Basic Classes
# Python class Person: def __init__(self, name: str, age: int): self.name = name self.age = age def greet(self) -> str: return f"Hello, I'm {self.name}"
// Scala class Person(val name: String, val age: Int) { def greet: String = s"Hello, I'm $name" } // Usage val person = new Person("Alice", 30) // 'new' required for class
Data Classes → Case Classes
# Python from dataclasses import dataclass @dataclass class Point: x: float y: float @dataclass(frozen=True) class ImmutablePoint: x: float y: float
// Scala - case class is idiomatic case class Point(x: Double, y: Double) // Case classes are immutable by default // They auto-generate: equals, hashCode, toString, copy, apply // Usage val p = Point(1.0, 2.0) // No 'new' needed for case class val p2 = p.copy(x = 3.0) // Creates new instance with x changed
Properties
# Python class Circle: def __init__(self, radius: float): self._radius = radius @property def radius(self) -> float: return self._radius @radius.setter def radius(self, value: float): if value < 0: raise ValueError("Radius must be non-negative") self._radius = value @property def area(self) -> float: return 3.14159 * self._radius ** 2
// Scala class Circle(private var _radius: Double) { require(_radius >= 0, "Radius must be non-negative") def radius: Double = _radius def radius_=(value: Double): Unit = { require(value >= 0, "Radius must be non-negative") _radius = value } def area: Double = math.Pi * _radius * _radius } // Idiomatic Scala: prefer immutable case class case class Circle(radius: Double) { require(radius >= 0, "Radius must be non-negative") def area: Double = math.Pi * radius * radius }
Inheritance
# Python class Animal: def __init__(self, name: str): self.name = name def speak(self) -> str: raise NotImplementedError class Dog(Animal): def speak(self) -> str: return f"{self.name} says woof!" class Cat(Animal): def speak(self) -> str: return f"{self.name} says meow!"
// Scala abstract class Animal(val name: String) { def speak: String // Abstract method } class Dog(name: String) extends Animal(name) { override def speak: String = s"$name says woof!" } class Cat(name: String) extends Animal(name) { override def speak: String = s"$name says meow!" }
Abstract Classes and Interfaces
# Python from abc import ABC, abstractmethod class Shape(ABC): @abstractmethod def area(self) -> float: pass @abstractmethod def perimeter(self) -> float: pass def describe(self) -> str: return f"Area: {self.area()}, Perimeter: {self.perimeter()}"
// Scala - abstract class abstract class Shape { def area: Double def perimeter: Double def describe: String = s"Area: $area, Perimeter: $perimeter" } // Scala - trait (preferred for interfaces) trait Shape { def area: Double def perimeter: Double def describe: String = s"Area: $area, Perimeter: $perimeter" } // Implementation case class Rectangle(width: Double, height: Double) extends Shape { def area: Double = width * height def perimeter: Double = 2 * (width + height) }
Multiple Inheritance → Traits
# Python class Flyable: def fly(self) -> str: return "Flying!" class Swimmable: def swim(self) -> str: return "Swimming!" class Duck(Animal, Flyable, Swimmable): def speak(self) -> str: return "Quack!"
// Scala - use traits for mixins trait Flyable { def fly: String = "Flying!" } trait Swimmable { def swim: String = "Swimming!" } class Duck(name: String) extends Animal(name) with Flyable with Swimmable { override def speak: String = "Quack!" }
Static Methods and Class Methods
# Python class MathUtils: PI = 3.14159 @staticmethod def add(a: int, b: int) -> int: return a + b @classmethod def from_string(cls, s: str) -> "MathUtils": return cls()
// Scala - use companion object class MathUtils { // Instance methods here } object MathUtils { val PI: Double = 3.14159 def add(a: Int, b: Int): Int = a + b def fromString(s: String): MathUtils = new MathUtils() } // Usage MathUtils.add(1, 2) MathUtils.PI
Factory Pattern
# Python class Shape: @staticmethod def create(shape_type: str) -> "Shape": if shape_type == "circle": return Circle() elif shape_type == "rectangle": return Rectangle() raise ValueError(f"Unknown shape: {shape_type}")
// Scala - companion object with apply sealed trait Shape case class Circle(radius: Double) extends Shape case class Rectangle(width: Double, height: Double) extends Shape object Shape { def apply(shapeType: String): Shape = shapeType match { case "circle" => Circle(1.0) case "rectangle" => Rectangle(1.0, 1.0) case other => throw new IllegalArgumentException(s"Unknown shape: $other") } } // Usage val shape = Shape("circle")
Enums
# Python from enum import Enum, auto class Color(Enum): RED = auto() GREEN = auto() BLUE = auto() class Status(Enum): PENDING = "pending" APPROVED = "approved" REJECTED = "rejected"
// Scala 3 enum Color: case Red, Green, Blue enum Status(val value: String): case Pending extends Status("pending") case Approved extends Status("approved") case Rejected extends Status("rejected") // Scala 2 - sealed trait pattern sealed trait Color object Color { case object Red extends Color case object Green extends Color case object Blue extends Color }
Singleton
# Python class Singleton: _instance = None def __new__(cls): if cls._instance is None: cls._instance = super().__new__(cls) return cls._instance
// Scala - object is a singleton object Singleton { def doSomething(): Unit = println("I'm a singleton!") } // Usage Singleton.doSomething()
Special Methods (Dunder Methods)
| Python | Scala |
|---|---|
| Primary constructor |
| |
| (case classes auto-generate) |
| (case classes auto-generate) |
| (case classes auto-generate) |
| or method |
| method |
| method |
| Extend trait |
| method |
, , etc. | Extend trait |
# Python class Vector: def __init__(self, x, y): self.x = x self.y = y def __add__(self, other): return Vector(self.x + other.x, self.y + other.y) def __str__(self): return f"Vector({self.x}, {self.y})"
// Scala case class Vector(x: Double, y: Double) { def +(other: Vector): Vector = Vector(x + other.x, y + other.y) // toString auto-generated by case class }