Object Slicing in Java

The term "object slicing" refers to the scenario that occurs when an object of a derived class is assigned to an instance of a base class. It results in the derived class object losing methods and member variables. It is referred to as information slicing. As an example,

B now contains two member variables, a1 and b1, because it extends A. So, if you establish a1 variable b1 of type B, then create a variable of type A and assign b1, you would lose the member variable b1. As an example,

The information in for regarding b is lost in a bar in this situation. It is referred to as member slicing.

The conversion of an object into something with less information (usually a superclass) is known as object slicing. It happens in C++ when an object is provided by value and duplicating the parameter value results in an upcast, which is regarded problematic since it can lead to extremely subtle problems. Object slicing wastes information. However, in certain cases, this may be precisely what we desire.

Objects are supplied by reference in Java, and all methods are virtual, therefore object slicing will not occur by accident. Even if an object is upcast, its true type is not lost; this is the definition of polymorphism.

Consider the most basic form of object slicing. Assume class Child extends class Parent, and we have a Child object. We would want to "extract" the Parent portion of it.

It does not work because the compiler will ensure that a dot is followed by a proper identifier after super.

Also, because this is polymorphic, returning a reference to it from the Parent class is useless. Overridden methods will be invoked instead of the Parent class's methods, and any extra methods will be accessible for invocation. That is precisely what we wish to prevent. We want a proxy to an object's underlying type, not only to limit the interface, and not merely a replica of the data and behavior.

We may establish a proxy to an object's base type in this way: for a subclass of that Parent type where a method is overridden, we additionally add a method that uses super to invoke the overridden method. Then we develop a wrapper to direct the calls to the appropriate methods. However, this is not elegant, as it necessitates keeping track of much too much information. The object-oriented approach is to use inner classes. Also, because we cannot execute a method with reflection on super, we cannot utilize dynamic proxies to avoid implementing each method from the base class.

How to Perform Object Slicing in Java?

Let's recall that in order to be instantiated, an inner class requires an instance of the surrounding class, and all members of the enclosing object are available from the inner class.

Our plan is to take use of this characteristic as well as the fact that, unlike this, super is not polymorphic.

We build an inner class Slice in the Child class, which extends Parent and overrides all of Parent's methods by forwarding them to the Parent component of the enclosing object. The Child class's getParent() function returns an instance of Slice, which acts as a proxy for the Parent section of the object.

Here is a test class that demonstrates that getParent() works as expected, i.e. it slices the object:

ObjectSlicing.java

Output:

der

You may be wondering why this would be beneficial. After all, we may avoid inheritance by having the Derived class store a reference of type Base, which would be created in a constructor or assigned via a setter function. It is not usually good practice. Consider the Human class, which requires enhancement from the Male and Female classes.

It makes no sense to need Male and Female instances to be constructed from previous Human instances. We have a true IS-A relationship here, and the Male and Female classes should help to extend the Human class. And, if we wish to prevent type discrimination in one of our layers, we must remove the extra information or behavior changes introduced by the subclasses.


Next TopicOracle Java




Latest Courses