OOP Concepts · Foundations

Static Members

Most members belong to each object. Static members belong to the class itself — one shared copy, used without creating an object.

Beginner 5 min Lesson 7 of 38 Runnable examplesExamples use modern JavaScript (ES2022 private fields) and C# 13.
Before you start:Classes and Objects
0/38 in OOP Concepts
On this page · 5 min · Beginner

In simple words#

A school has one notice board shared by every student. Static members belong to the class itself (shared), not to each individual object.

static
Belongs to the class, not an object.
Instance member
Each object has its own copy.
Static method
Called as ClassName.Method().

Learning objectives#

  • Explain instance vs static members
  • Use static fields for shared data and constants
  • Write static factory and utility methods
  • Know the limits and risks of static state

Explanation#

Instance members belong to each object: every Order has its own amount. Static members belong to the class: Order.count is one number shared by all orders.

Call static members on the class, not on an object: Order.count, Math.max(), not order.count.

Good uses: constants (Order.TAX_RATE), counters and ID generators, factory methods (Order.fromCsv(line)) and utility classes (MathUtil.clamp).

A static method cannot use this to reach an object’s data, because it is not called on any object.

In C#, a static class (static class MathUtil) can only contain static members and cannot be instantiated. Be careful with mutable static state in web apps — it is shared by every request and every user.

Syntax#

C# Illustrative
public class Order
{
    private static int _nextId = 1;           // shared by all orders
    public const decimal TaxRate = 0.18m;      // constant (implicitly static)


    public int Id { get; } = _nextId++;


    public static Order FromCsv(string line) => new Order();   // factory
}


public static class MathUtil
{
    public static int Clamp(int v, int min, int max) => Math.Min(Math.Max(v, min), max);
}

Code example: Order IDs, counters and helpers#

JavaScriptOrder IDs, counters and helpers Runnable
class Order {
  static #nextId = 1;        // private, shared
  static count = 0;          // public, shared
  static TAX_RATE = 0.18;    // constant


  constructor(amount) {
    this.id = Order.#nextId++;
    this.amount = amount;
    Order.count++;
  }


  get totalWithTax() {
    return Math.round(this.amount * (1 + Order.TAX_RATE));
  }


  static fromCsv(line) {     // factory method
    const [amount] = line.split(',');
    return new Order(Number(amount));
  }
}


class MathUtil {
  static clamp(value, min, max) {
    return Math.min(Math.max(value, min), max);
  }
}


const a = new Order(100);
const b = new Order(250);
const c = Order.fromCsv('400,INR');


console.log(a.id, b.id, c.id);
console.log('Orders created:', Order.count);
console.log(b.totalWithTax);
console.log(a.count);
console.log(MathUtil.clamp(150, 0, 100));
Expected output
1 2 3
Orders created: 3
295
undefined
100
Opens this example in the full playground

Step-by-step explanation#

  1. Order.#nextId is shared, so each new order gets the next number.
  2. Order.count is incremented by every constructor call — one counter for all orders.
  3. fromCsv is a static factory: it builds an Order from text, called on the class.
  4. a.count is undefined because count lives on the class, not on each object.
  5. MathUtil only groups helper functions; it never needs an instance.

Real-world use case#

In C#, DateTime.Now, Guid.NewGuid() and Math.Round() are static. In your own code, a static Result.Success(value) factory or a static Slug.Create(title) helper reads naturally and needs no object.

Common mistakes#

Shared mutable state in web apps

A static List<Order> in an ASP.NET Core app is shared by every user and every request — and is not thread-safe. Use a database or a scoped service.

Accessing this in a static method

There is no object in a static method, so this does not refer to an instance (in C# it is a compile error).

Static everything

Static methods cannot be swapped with fakes in tests. Logic that talks to databases or APIs belongs in injectable services.

Best practices#

  • Use static for constants, pure helpers and factory methods
  • Avoid mutable static state
  • Call static members through the class name
  • Prefer dependency-injected services for anything with side effects

Remember this#

Instance = one per object. Static = one per class.

Call it on the class: Order.count, not order.count.

Static + mutable + web app = trouble.

Practice exercise#

Your task: Create a Temperature class with a static method fromFahrenheit(f) that returns a new Temperature in Celsius, and a static constant FREEZING = 0.

Need a hint?
Celsius = (f - 32) * 5 / 9. Return new Temperature(celsius).
Show solution
JavaScript Runnable
class Temperature {
  static FREEZING = 0;
  constructor(celsius) { this.celsius = celsius; }
  static fromFahrenheit(f) { return new Temperature(((f - 32) * 5) / 9); }
}
const t = Temperature.fromFahrenheit(212);
console.log(t.celsius);                          // 100
console.log(t.celsius > Temperature.FREEZING);   // true
Opens this example in the full playground

Mini quiz#

Static Members quizPredict the output Question 1 of 3

What is logged?

class Hit { static total = 0; constructor() { Hit.total++; } }
new Hit(); new Hit(); new Hit();
console.log(Hit.total);
Score so far: 0/0

Want more? Practise all OOP Concepts MCQs · OOP Concepts interview questions

My notes#

Saved in this browser.

Progress is saved in this browser. Sign in to sync.