Getters and Setters
Getters and Setters#
Getters and setters provide controlled access to private class attributes, implementing encapsulation. A getter retrieves attribute values, while a setter modifies them. They serve as a protective interface between an object's internal state and external code.
Core Concept#
Getters and setters enable validation, data transformation, logging, and other operations when attributes are accessed or modified. This prevents direct access to internal state, maintaining object integrity and allowing classes to enforce business rules.
Access Control Flow#
graph LR
A["Client Code"] --> B["Getter/Setter Method"]
B --> C["Validation & Processing"]
C --> D["Private Attribute"]
style A fill:#e8f5e8
style B fill:#c8e6c9
style C fill:#fff3e0
style D fill:#e3f2fd
This diagram shows how client code accesses private attributes through controlled methods that can validate and process data.
Benefits of Getters and Setters#
graph TD
A["Getters & Setters"] --> B["Data Validation"]
A --> C["Access Control"]
A --> D["Computed Properties"]
A --> E["Logging & Monitoring"]
A --> F["Business Rules"]
style A fill:#e8f5e8
style B fill:#c8e6c9
style C fill:#ffcdd2
style D fill:#e3f2fd
style E fill:#fff3e0
style F fill:#f3e5f5
This diagram illustrates the key benefits that getters and setters provide in object-oriented programming.
Implementation Examples#
Let's explore how different programming languages implement these controlled access mechanisms:
public class Guitar {
private String brand;
private double price;
public Guitar(String brand, double price) {
this.brand = brand;
this.price = price;
}
// Getter
public String getBrand() {
return brand;
}
// Setter with validation
public void setPrice(double price) {
if (price > 0) {
this.price = price;
}
}
}
// Usage
Guitar guitar = new Guitar("Fender", 1000.0);
System.out.println(guitar.getBrand()); // Fender
guitar.setPrice(1500.0); // Valid price
guitar.setPrice(-100); // Ignored (validation)
class Guitar(private var _brand: String, private var _price: Double) {
// Custom getter
val brand: String
get() = _brand.uppercase()
// Custom setter with validation
var price: Double
get() = _price
set(value) {
if (value > 0) _price = value
}
}
// Usage
val guitar = Guitar("Fender", 1000.0)
println(guitar.brand) // FENDER (uppercase)
guitar.price = 1500.0 // Valid
guitar.price = -100 // Ignored
class Guitar {
private _brand: string;
private _price: number;
constructor(brand: string, price: number) {
this._brand = brand;
this._price = price;
}
// Getter
get brand(): string {
return this._brand;
}
// Setter with validation
set price(value: number) {
if (value > 0) {
this._price = value;
}
}
}
// Usage
const guitar = new Guitar("Fender", 1000.0);
console.log(guitar.brand); // Fender
guitar.price = 1500.0; // Valid
guitar.price = -100; // Ignored
class Guitar {
String _brand;
double _price;
Guitar(this._brand, this._price);
// Getter
String get brand => _brand;
// Setter with validation
set price(double value) {
if (value > 0) _price = value;
}
}
// Usage
Guitar guitar = Guitar("Fender", 1000.0);
print(guitar.brand); // Fender
guitar.price = 1500.0; // Valid
guitar.price = -100; // Ignored
class Guitar {
private var _brand: String
private var _price: Double
init(brand: String, price: Double) {
self._brand = brand
self._price = price
}
// Getter
var brand: String {
return _brand
}
// Setter with validation
var price: Double {
get { return _price }
set {
if newValue > 0 {
_price = newValue
}
}
}
}
// Usage
let guitar = Guitar(brand: "Fender", price: 1000.0)
print(guitar.brand) // Fender
guitar.price = 1500.0 // Valid
guitar.price = -100 // Ignored
class Guitar:
def __init__(self, brand, price):
self._brand = brand
self._price = price
@property
def brand(self):
return self._brand
@property
def price(self):
return self._price
@price.setter
def price(self, value):
if value > 0:
self._price = value
# Usage
guitar = Guitar("Fender", 1000.0)
print(guitar.brand) # Fender
guitar.price = 1500.0 # Valid
guitar.price = -100 # Ignored