Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.

To use data from another class, your code needs a reference to the object that owns the data, plus permission to access the member. The basic instance-member syntax is object.member. If the member is private, use an accessor or other public interface supplied by its class; for shared class-level data, use ClassName.member.

First identify what kind of variable you mean

“Variable” can refer to several different things in object-oriented code, and each has different access rules:

  • Instance field or attribute: Data belonging to one particular object, such as one person’s name.
  • Static or class variable: Data associated with the class and shared or reachable at the class level.
  • Property: A member that looks like data when used but can run code when read or written. This is common in C#.
  • Local variable: A name declared inside a method or block. It is limited to that scope and is not accessible through an object.
  • Constant: A value intended not to change after initialization; its syntax and guarantees depend on the language.

Also distinguish the class from an object: a class defines a type, while an object is a particular instance of that type. Accessing the right kind of member on the wrong object will not give you the data you intended.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Access an instance member through the object

If a member is public, another class can generally use it through a reference to the relevant object. In Java, for example:

class Person {
    public String name = "Alex";
}

class Main {
    public static void main(String[] args) {
        Person person = new Person();
        System.out.println(person.name);
    }
}

The steps are to create or receive a Person object, keep its reference in person, then use the dot operator: person.name. The general pattern is:

ClassName object = new ClassName();
object.memberName;

A public field is convenient, but it also lets outside code read or change the representation directly. For example, a caller could assign a value that leaves the object in an invalid state. Microsoft’s C# guidance explains this trade-off for public fields: public fields and field usage.

For private data, use an exposed interface

In languages with enforced private access, such as Java, an unrelated class cannot directly read a private field. The class that owns the field can expose a getter, setter, property, or a meaningful operation instead. Here is a Java example:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
class Person {
    private String name;

    public Person(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        if (name != null && !name.isBlank()) {
            this.name = name;
        }
    }
}

class Main {
    public static void main(String[] args) {
        Person person = new Person("Alex");
        System.out.println(person.getName());
        person.setName("Jordan");
    }
}

From the other class, person.name is an access error, while person.getName() is allowed. A getter reads a value; a setter requests a change and can validate it. A setter is not mandatory: if outside code should only read a value, expose only a getter. If a change expresses a domain action, a method such as rename("Jordan") may communicate intent better than a generic setter.

Java access levels include private, protected, public, and package access (when no modifier is written). The exact boundary matters; see Oracle’s overview of Java object-oriented programming and access modifiers.

C# usually uses properties

C# callers commonly use properties rather than Java-style getName() and setName() methods. A property can allow reading publicly while restricting who may write:

public class Person
{
    public string Name { get; private set; }

    public Person(string name)
    {
        Name = name;
    }
}

public class Program
{
    public static void Main()
    {
        Person person = new Person("Alex");
        Console.WriteLine(person.Name);
        // person.Name = "Jordan"; // Not allowed here: the setter is private
    }
}

Name is publicly readable, but only code inside Person can assign it. A read/write property could use public string Name { get; set; }; a getter-only property can use public string Name { get; }. Properties are distinct from fields even though their use looks field-like: accessors can contain logic. Microsoft documents these patterns in its C# properties guide and its instructions for declaring and using read/write properties.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Python attributes and properties

Python commonly allows direct attribute access for simple data:

class Person:
    def __init__(self, name):
        self.name = name

class Greeter:
    def greet(self, person):
        return f"Hello, {person.name}"

person = Person("Alex")
print(Greeter().greet(person))

Use a property when reading or assigning the attribute should involve validation, calculation, compatibility, or other behavior:

class Person:
    def __init__(self, name):
        self._name = name

    @property
    def name(self):
        return self._name

    @name.setter
    def name(self, value):
        if not value:
            raise ValueError("Name cannot be empty")
        self._name = value

person = Person("Alex")
print(person.name)
person.name = "Jordan"

A single leading underscore, as in _name, is a convention that marks an attribute as non-public; it does not prevent access. A double-leading underscore, as in __name, triggers name mangling to reduce accidental name collisions, not to create absolute privacy. Python’s documentation explicitly notes that strictly inaccessible private instance variables do not exist: Python tutorial: classes.

Access a static or class variable by class name

An instance field belongs to one object. A static or class variable is associated with the class, so access it through the class name when that is the intended meaning:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
// Java
class Counter {
    public static int count = 0;
}
System.out.println(Counter.count);
// C#
public class Counter
{
    public static int Count = 0;
}
Console.WriteLine(Counter.Count);
# Python
class Counter:
    count = 0

print(Counter.count)

Use object.member for per-object state and ClassName.member for class-level state. Do not create an object just to access a static member. Conversely, a class name cannot stand in for an object when the data belongs to one particular instance. Static mutable state can also make testing, concurrency, and program behavior harder to reason about, so use it because the value truly belongs to the type—not simply as a convenient global.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Inheritance changes which members a subclass can use

A subclass can use some inherited members according to their visibility, but inheritance does not give every other class access. In Java, a protected member is accessible within its package and by subclasses; a private member is not directly available to a subclass. C# has its own access rules and modifiers, including protected and internal. These rules are language-specific; consult the relevant language documentation rather than assuming one universal meaning. Oracle’s Java access-modifier overview and Microsoft’s C# object-oriented programming guide describe their respective models.

class Parent {
    protected int value = 42;
}

class Child extends Parent {
    public void printValue() {
        System.out.println(value);
    }
}

Use a protected field only when subclasses are deliberately meant to depend on that representation. A protected method or property often gives the base class better control over how its state is used.

Pass the object that contains the data

Often the main problem is not visibility but getting the right object into the class that needs it. Pass the existing object as a constructor or method argument instead of creating a replacement:

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
class Report {
    private Person person;

    public Report(Person person) {
        this.person = person;
    }

    public void printName() {
        System.out.println(person.getName());
    }
}

Person person = new Person("Alex");
Report report = new Report(person);
report.printName();

new Person(...) creates a separate object. Passing person gives Report a reference to the particular instance whose data it should use. This is also useful when a method only needs the object temporarily: accept it as a parameter rather than storing it.

Common errors and how to fix them

  • “Field is private” error: Do not make the field public just to silence the compiler. Add a getter, a suitably restricted property, or a method that expresses the operation the caller needs.
  • Using a class name for instance data: Person.name is not the right form for a normal instance field. Get an object first, then use person.name or its accessor.
  • Creating a different object: new Person() does not give access to an earlier Person object’s state. Pass the existing reference.
  • Confusing a local variable with a field: A variable declared inside a method exists only in that scope. Declare object state in the class body if it must persist as part of an object.
  • Shadowing a field with a parameter: In a Java constructor, name = name; assigns the parameter to itself. Write this.name = name; to assign the parameter to the current object’s field.
  • Mixing up getters and setters: A no-argument getter reads; a setter or behavior method changes. For example, use person.setName("Alex") if that setter exists.
  • Assuming Python privacy is enforced like Java’s: A leading underscore signals intended internal use but does not block outside access.

Choose the narrowest useful access

  • Use a public field or attribute when open access is intentional and unrestricted reads or writes are safe—often for simple data structures, though conventions differ by language.
  • Use a private field with a getter when callers should read but not change the value.
  • Allow changes through a validating setter or a meaningful operation when the class must protect its invariants.
  • Use a C# property when field-like access should have controlled read and write behavior.
  • Use a static/class member only for data that belongs to the type rather than to one instance.
  • Pass an object reference explicitly when another class needs to work with that particular object.

The goal is not simply to make data reachable. It is to let another class use the capability it needs without exposing more of the object’s internal state than necessary.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.