Object Misconceptions
Object-oriented programming is the current standard in most programming courses. After all, it is one of the most common paradigms…
Object Misconceptions
Object-oriented programming is the current standard in most programming courses. After all, it is one of the most common paradigms currently in use. Yet it is also one of the most challenging concepts for students to wrap their heads around. As instructors, we try to come up with as many analogies, explanations, and examples to make sure our students understand how classes and objects work. But unfortunately these can cause certain misconceptions among our students. A paper by Holland et al [1] covers some of these misconceptions. Although quite old (published back in 1997), it covers various misconceptions that to this day happen quite often. Understanding why these misconceptions form can help us address them before they cause too much trouble for our students. We will go through each of the misconceptions covered in the paper and explore them through actual examples.
Avoiding Object/Variable Conflation
This is actually a rather easy misconception to form due to how initial examples are presented. Examples tend to be simplified a lot. But sometimes we can simplify too much as in the example below.
class Account{
int balance;
Account()
{
balance = 0;
}
Account(int init)
{
balance = init;
}
}
The example above shows how to make a basic Account class. It only contains a balance and two constructors. Simple enough to understand. But also simple enough to misunderstand. What exactly does the Account class do? This version of the Account class seems to just add an additional layer between the variable balance and the user/programmer. Although there are useful wrapper classes in Java, particularly for primitive data types, that is not the main purpose of classes. So only providing examples like the one above may lead students to believe that all classes are simply wrapper classes when they actually do more. Adding more variables to the class, particularly of different data types, can help alleviate this but it can also lead to the next misconception. That is why it is important to show students that classes create objects which have states and take actions based on those states. Perhaps not as a first example but such examples should be shown shortly after introducing classes and objects. An easy way to do this is shown below.
class Account{
int balance;
int accountNumber;
String name;
Account()
{
balance = 0;
accountNumber = 0000;
name = "empty";
}
Account(int init, int clientID, String client)
{
balance = init;
accountNumber = clientID;
name = client;
}
boolean withdraw(int amount)
{
if(balance <= 0 || amount > balance)
{
System.out.println("Not enough in your balance…");
return false;
}
balance = balance - amount;
return true;
}
}
This example contains multiple variables of different data types (int, String) and performs some actions based on the state of the object (balance is greater than 0 or not, amount is less than or equal to balance or not). It demonstrates that objects are not simple variable wrappers but can take actions depending on their states and other factors.
Objects are not Simple Records
This misconception kind of goes hand-in-hand with the previous one. If students believe classes behave just like wrappers for variables, it logically follows that multiple variables can be stored in said classes, essentially using them as records.
class Account{
int balance;
int accountNumber;
String name;
Account()
{
balance = 0;
accountNumber = 0000;
name = "empty";
}
Account(int init, int clientID, String client)
{
balance = init;
accountNumber = clientID;
name = client;
}
void setBalance(int newBalance)
{
balance = newBalance;
}
void changeName(String newName)
{
name = newName;
}
int getBalance()
{
return balance;
}
int getAccount()
{
return accountNumber;
}
String getClientName()
{
return name;
}
}
The above example shows exactly that. Account contains multiple variables of different data types and simply retrieves them or sets new ones. It doesn’t perform any actions based on its state. The Account class functions just like a collection of data i.e. a record. That is why we need to make sure we show examples of classes that do more than just collecting data. We need to show how the state of an object influences its actions. Java already has records (as of JDK 14 although they do function a bit differently) while C++ has structs which essentially work like records.
//Example of a struct in C++ being used as a record
struct Point{
int x;
int y;
}
int main(){
Point p1;
p1.x = 1;
p1.y = 2;
}
Work in Methods is Not All Done by Assignment
Another common misconception when students think that all the actions done by objects are just variations of assigning values to internal variables. Although this does happen often, objects can do more than just assign values. Once again, this misconception can happen due to oversimplification of our examples. Perhaps our example classes only contain primitive data types and methods to retrieve or modify them. If that’s the case, pretty much most of what we can do with them is just assigning values to them. When our objects contain other objects or non-primitive data types, we can change their states internally through inputs or due to the other variables or objects inside the current object. We can see an example of this below. Client has a collection of Account objects stored in an ArrayList which can be modified. This changes the state of the Account object inside Client. Furthermore, certain changes to all of the Account objects can change the state of Client (i.e. all accounts have 0 or negative balances so the client is bankrupt). The internal states of non-primitive data types can change the overall state of the object. And these changes do not necessarily happen just from assigning new values to variables.
class Client{
String name;
int clientID;
boolean bankrupt;
ArrayList<Account> accounts;
Client(String n, int cID)
{
//Initializing variables
}
void addAccount(Account acc)
{
//Some implementation of adding accounts to ArrayList
}
boolean updateAccount(Account acc)
{
//Some implementation of updating specific account
}
boolean checkClientBankruptcy()
{
//Some implementation of checking for bankruptcy
}
/*********************************************************************
Some additional methods to change the states of Client or Account
*********************************************************************/
}
class Account{
int accountNumber;
int balance;
Client accountClient;
Account(int aN, int b, Client aC)
{
//Initializing variables
}
boolean withdraw(int amount)
{
//Some implementation of withdraw
}
boolean deposit(int amount)
{
//Some implementation of deposit
}
/*********************************************************************
Some additional methods to change the states of Client or Account
*********************************************************************/
}
Object/Class Conflation
Possibly the easiest misconception to correct although it can also be the easiest one to form. Classes and objects tend to be relatively new abstractions for students so it can be easy for them to conflate both concepts. A simple analogy many instructors use to explain the difference is how classes are the cookie cutters and objects are the actual cookies. This can work but it is not enough. Students need to see multiple examples of the differences between classes and objects? How do we do this? Create a class then make several instances of said class. Using the previous Account class as an example, we can create multiple Account objects for one person (people can have multiple bank accounts). Then carry out different actions on each account. This makes it clear that objects are not classes.
class Account{
…
/*Some implementation of Account*/
…
}
class Client{
…
/*Some implementation of Client*/
…
}
class Main{
public static void main(String [] args){
//A Client object with two Account objects linked to it
Client James = new Client();
Account jamesAcc1 = new Account(James, 500);
Account jamesAcc2 = new Account(James, 2000);
}
}
Identity/Attribute Confusion
This can be one of the trickier misconceptions to identify as it is common even among many instructors if they don’t have much experience creating and manipulating objects. This misconception mainly has to do with conflating attributes of the object with the object itself. What does that mean? In object-oriented programming, attributes are the specific properties of a class i.e. the variables in a class. Sometimes, students conflate these variables and the object they contain as the same thing. That is a major problem. This is not the same as the first misconception we covered (considering classes as variable wrappers) but something fundamentally different. We can easily see what the problem is with the following example.
Client Bob = new Client("Bob", 1234);
Client Rick = Bob;
System.out.println(Bob.getID());
System.out.println(Rick.getID());
Bob = null; //deleting Bob
System.out.println(Rick.getID());
If a student believes that the variable Bob and the object it points to are the same thing, then they would conclude that the final print statement will result in an error since it does not exist anymore. But that is not the case. The object Bob pointed to still exists, it’s just that variable Rick points to it now. Even if Rick did not exist, the object would still exist in memory for some time until the garbage collector deletes it, if there is one (Java has one). If there isn’t (like in C++), the object would remain in memory even after the program terminates resulting in memory leakage which is a major problem. This misconception also leads to misunderstanding how the code below works.
Client Bob = new Client("Bob", 1234);
Client Rick = Bob;
System.out.println(Bob.getID());
System.out.println(Rick.getID());
Bob.changeID(9876);
System.out.println(Bob.getID());
System.out.println(Rick.getID());
A student with the same misunderstanding as before would think they just changed the ID for Bob when they actually changed the ID for the object Bob is pointing to. Since Rick points to the same object, it will retrieve the same ID as Bob. They unintentionally changed something they did not want to. That also leads to another problem as shown in the following code.
Client Bob = new Client("Bob", 1234);
Client Rick = new Client("Bob", 1234);
System.out.println(Bob.getID());
System.out.println(Rick.getID());
Bob.changeID(9876);
System.out.println(Bob.getID());
System.out.println(Rick.getID());
Since both Bob and Rick have the same data, changing the ID of Bob should change the ID of Rick, shouldn’t it? Nope. That’s because Bob and Rick point to different objects with the same data. These examples actually refer to a concept called shallow copies and deep copies which is rather fundamental in object-oriented programming. The first two snippets of code are examples of shallow copies while the last one is an example of a deep copy (sort of). Shallow copies are basically when several variables point to the same object in a specific memory location. Changing the attributes of the object will affect all variables pointing to it. Deep copies are when multiple variables point to multiple objects (each variable points to a unique object) and each object contains exactly the same attributes. So modifying the attributes of one object only affects that object and the variable pointing to it, not the other objects or variables.
How can we address this misconception? By showing examples like the previous ones and asking students what they think will happen, then actually showing them what happens. Then we should let them experiment by allowing them to create multiple objects and variables and assigning them in various ways to see what happens. This technique is effective not just for the previous misconception but for any misconception that students form. It’s through experimentation like this that students learn best. Simply showing them how it works isn’t enough (as explained in this Veritasium video about science learning through digital media). How and why addressing misconceptions first works though is for another time. Hopefully, the paper by Holland et al and the examples provided above provide a deeper insight into why students form certain misconceptions about object-oriented programming and how we can address them.
[1] Avoiding Object Misconceptions: Simon Holland, Robert Griffiths, Mark Woodman. https://dl.acm.org/doi/abs/10.1145/268084.268132
메타데이터
- post_id
- 165245d93536
- slug
- object-misconceptions-165245d93536
- url
- https://medium.com/@compuxela/object-misconceptions-165245d93536
- canonical_url
- https://medium.com/@compuxela/object-misconceptions-165245d93536
- author_url
- https://medium.com/@compuxela
- status
- ok
- fetched_at
- 2026-09-14 01:12:41