Object Slicing, Is it advantage? - oop

Object slicing is some thing that object looses some of its attributes or functions when a child class is assigned to base class.
Some thing like
Class A{
}
Class B extends A{
}
Class SomeClass{
A a = new A();
B b = new B();
// Some where if might happen like this */
a = b; (Object slicing happens)
}
Do we say Object slicing is any beneficial in any ways?
If yes, can any one please tell me how object slicing be a helpful in development and where it might be helpful?

In C++, you should think of an object slice as a conversion from the derived type to the base type[*]. A brand new object is created, which is "inspired by a true story".
Sometimes this is something that you would want to do, but the result is not in any sense the same object as the original. When object slicing goes wrong is when people aren't paying attention, and think it is the same object or a copy of it.
It's normally not beneficial. In fact it's normally done accidentally when someone passes by value when they meant to pass by reference.
It's quite hard to come up with an example of when slicing is definitively the right thing to do, because it's quite hard (especially in C++) to come up with an example where a non-abstract base class is definitively the right thing to do. This is an important design point, and not one to pass over lightly - if you find yourself slicing an object, either deliberately or accidentally, quite likely your object hierarchy is wrong to start with. Either the base class shouldn't be used as a base class, or else it should have at least one pure virtual function and hence not be sliceable or passable by value.
So, any example I gave where an object is converted to an object of its base class, would rightly provoke the objection, "hang on a minute, what are you doing inheriting from a concrete class in the first place?". If slicing is accidental then it's probably a bug, and if it's deliberate then it's probably "code smell".
But the answer might be "yes, OK, this shouldn't really be how things are structured, but given that they are structured that way, I need to convert from the derived class to the base class, and that by definition is a slice". In that spirit, here's an example:
struct Soldier {
string name;
string rank;
string serialNumber;
};
struct ActiveSoldier : Soldier {
string currentUnit;
ActiveSoldier *commandingOfficer; // the design errors multiply!
int yearsService;
};
template <typename InputIterator>
void takePrisoners(InputIterator first, InputIterator last) {
while (first != last) {
Soldier s(*first);
// do some stuff with name, rank and serialNumber
++first;
}
}
Now, the requirement of the takePrisoners function template is that its parameter be an iterator for a type convertible to Soldier. It doesn't have to be a derived class, and we don't directly access the members "name", etc, so takePrisoners has tried to offer the easiest possible interface to implement given the restrictions (a) should work with Soldier, and (b) should be possible to write other types that it also works with.
ActiveSoldier is one such other type. For reasons best known only to the author of that class, it has opted to publicly inherit from Soldier rather than providing an overloaded conversion operator. We can argue whether that's ever a good idea, but let's suppose we're stuck with it. Because it's a derived class, it is convertible to Soldier. That conversion is called a slice. Hence, if we call takePrisoners passing in the begin() and end() iterators for a vector of ActiveSoldiers, then we will slice them.
You could probably come up with similar examples for an OutputIterator, where the recipient only cares about the base class part of the objects being delivered, and so allows them to be sliced as they're written to the iterator.
The reason it's "code smell" is that we should consider (a) rewriting ActiveSoldier, and (b) changing Soldier so that it can be accessed using functions instead of member access, so that we can abstract that set of functions as an interface that other types can implement independently, so that takePrisoners doesn't have to convert to Soldier. Either of those would remove the need for a slice, and would have potential benefits for the ease with which our code can be extended in future.
[*] because it is one. The last two lines below are doing the same thing:
struct A {
int value;
A(int v) : value(v) {}
};
struct B : A {
int quantity;
B(int v, int q) : A(v), quantity(q) {}
};
int main() {
int i = 12; // an integer
B b(12, 3); // an instance of B
A a1 = b; // (1) convert B to A, also known as "slicing"
A a2 = i; // (2) convert int to A, not known as "slicing"
}
The only difference is that (1) calls A's copy constructor (that the compiler provides even though the code doesn't), whereas (2) calls A's int constructor.
As someone else said, Java doesn't do object slicing. If the code you provide were turned into Java, then no kind of object slicing would happen. Java variables are references, not objects, so the postcondition of a = b is just that the variable "a" refers to the same object as the variable "b" - changes via one reference can be seen via the other reference, and so on. They just refer to it by a different type, which is part of polymorphism. A typical analogy for this is that I might think of a person as "my brother"[**], and someone else might think of the same person as "my vicar". Same object, different interface.
You can get the Java-like effect in C++ using pointers or references:
B b(24,7);
A *a3 = &b; // No slicing - a3 is a pointer to the object b
A &a4 = b; // No slicing - a4 is a reference to (pseudonym for) the object b
[**] In point of fact, my brother is not a vicar.

Related

Mixing Private and Public Attributes and Accessors in Raku

#Private attribute example
class C {
has $!w; #private attribute
multi method w { $!w } #getter method
multi method w ( $_ ) { #setter method
warn “Don’t go changing my w!”; #some side action
$!w = $_
}
}
my $c = C.new
$c.w( 42 )
say $c.w #prints 42
$c.w: 43
say $c.w #prints 43
#but not
$c.w = 44
Cannot modify an immutable Int (43)
so far, so reasonable, and then
#Public attribute example
class C {
has $.v is rw #public attribute with automatic accessors
}
my $c = C.new
$c.v = 42
say $c.v #prints 42
#but not
$c.v( 43 ) #or $c.v: 43
Too many positionals passed; expected 1 argument but got 2
I like the immediacy of the ‘=‘ assignment, but I need the ease of bunging in side actions that multi methods provide. I understand that these are two different worlds, and that they do not mix.
BUT - I do not understand why I can’t just go
$c.v( 43 )
To set a public attribute
I feel that raku is guiding me to not mix these two modes - some attributes private and some public and that the pressure is towards the method method (with some : sugar from the colon) - is this the intent of Raku's design?
Am I missing something?
is this the intent of Raku's design?
It's fair to say that Raku isn't entirely unopinionated in this area. Your question touches on two themes in Raku's design, which are both worth a little discussion.
Raku has first-class l-values
Raku makes plentiful use of l-values being a first-class thing. When we write:
has $.x is rw;
The method that is generated is:
method x() is rw { $!x }
The is rw here indicates that the method is returning an l-value - that is, something that can be assigned to. Thus when we write:
$obj.x = 42;
This is not syntactic sugar: it really is a method call, and then the assignment operator being applied to the result of it. This works out, because the method call returns the Scalar container of the attribute, which can then be assigned into. One can use binding to split this into two steps, to see it's not a trivial syntactic transform. For example, this:
my $target := $obj.x;
$target = 42;
Would be assigning to the object attribute. This same mechanism is behind numerous other features, including list assignment. For example, this:
($x, $y) = "foo", "bar";
Works by constructing a List containing the containers $x and $y, and then the assignment operator in this case iterates each side pairwise to do the assignment. This means we can use rw object accessors there:
($obj.x, $obj.y) = "foo", "bar";
And it all just naturally works. This is also the mechanism behind assigning to slices of arrays and hashes.
One can also use Proxy in order to create an l-value container where the behavior of reading and writing it are under your control. Thus, you could put the side-actions into STORE. However...
Raku encourages semantic methods over "setters"
When we describe OO, terms like "encapsulation" and "data hiding" often come up. The key idea here is that the state model inside the object - that is, the way it chooses to represent the data it needs in order to implement its behaviors (the methods) - is free to evolve, for example to handle new requirements. The more complex the object, the more liberating this becomes.
However, getters and setters are methods that have an implicit connection with the state. While we might claim we're achieving data hiding because we're calling a method, not accessing state directly, my experience is that we quickly end up at a place where outside code is making sequences of setter calls to achieve an operation - which is a form of the feature envy anti-pattern. And if we're doing that, it's pretty certain we'll end up with logic outside of the object that does a mix of getter and setter operations to achieve an operation. Really, these operations should have been exposed as methods with a names that describes what is being achieved. This becomes even more important if we're in a concurrent setting; a well-designed object is often fairly easy to protect at the method boundary.
That said, many uses of class are really record/product types: they exist to simply group together a bunch of data items. It's no accident that the . sigil doesn't just generate an accessor, but also:
Opts the attribute into being set by the default object initialization logic (that is, a class Point { has $.x; has $.y; } can be instantiated as Point.new(x => 1, y => 2)), and also renders that in the .raku dumping method.
Opts the attribute into the default .Capture object, meaning we can use it in destructuring (e.g. sub translated(Point (:$x, :$y)) { ... }).
Which are the things you'd want if you were writing in a more procedural or functional style and using class as a means to define a record type.
The Raku design is not optimized for doing clever things in setters, because that is considered a poor thing to optimize for. It's beyond what's needed for a record type; in some languages we could argue we want to do validation of what's being assigned, but in Raku we can turn to subset types for that. At the same time, if we're really doing an OO design, then we want an API of meaningful behaviors that hides the state model, rather than to be thinking in terms of getters/setters, which tend to lead to a failure to colocate data and behavior, which is much of the point of doing OO anyway.
BUT - I do not understand why I can’t just go $c.v( 43 ) To set a public attribute
Well, that's really up to the architect. But seriously, no, that's simply not the standard way Raku works.
Now, it would be entirely possible to create an Attribute trait in module space, something like is settable, that would create an alternate accessor method that would accept a single value to set the value. The problem with doing this in core is, is that I think there are basically 2 camps in the world about the return value of such a mutator: would it return the new value, or the old value?
Please contact me if you're interested in implementing such a trait in module space.
I currently suspect you just got confused.1 Before I touch on that, let's start over with what you're not confused about:
I like the immediacy of the = assignment, but I need the ease of bunging in side actions that multi methods provide. ... I do not understand why I can’t just go $c.v( 43 ) To set a public attribute
You can do all of these things. That is to say you use = assignment, and multi methods, and "just go $c.v( 43 )", all at the same time if you want to:
class C {
has $!v;
multi method v is rw { $!v }
multi method v ( :$trace! ) is rw { say 'trace'; $!v }
multi method v ( $new-value ) { say 'new-value'; $!v = $new-value }
}
my $c = C.new;
$c.v = 41;
say $c.v; # 41
$c.v(:trace) = 42; # trace
say $c.v; # 42
$c.v(43); # new-value
say $c.v; # 43
A possible source of confusion1
Behind the scenes, has $.foo is rw generates an attribute and a single method along the lines of:
has $!foo;
method foo () is rw { $!foo }
The above isn't quite right though. Given the behavior we're seeing, the compiler's autogenerated foo method is somehow being declared in such a way that any new method of the same name silently shadows it.2
So if you want one or more custom methods with the same name as an attribute you must manually replicate the automatically generated method if you wish to retain the behavior it would normally be responsible for.
Footnotes
1 See jnthn's answer for a clear, thorough, authoritative accounting of Raku's opinion about private vs public getters/setters and what it does behind the scenes when you declare public getters/setters (i.e. write has $.foo).
2 If an autogenerated accessor method for an attribute was declared only, then Raku would, I presume, throw an exception if a method with the same name was declared. If it were declared multi, then it should not be shadowed if the new method was also declared multi, and should throw an exception if not. So the autogenerated accessor is being declared with neither only nor multi but instead in some way that allows silent shadowing.

How to handle polymorphic objects

I am planning to port our server to Go from c++ and I have a question with regards to handling a list of objects based from derived classes.
What I meant is, say if I have a base class (or an interface) called A, and it has child classes B and C, and I want to have a generic list that can handle a list of Type A and it's derived.
In object oriented languages, I can just create a list of (pointer) A and that's it, I can add objects B and C to the list because they are indeed of type A. But since Go does not have inheritance, I am confused on how to effectively handle this.
As noted before, you can do this using interfaces. You can create a list of type []Intf where Intf is an interface common to your types, and then you can put any type that implements that interface into your list.
type A struct{}
type B struct{}
type Intf interface {
// common methods of A and B
}
func f(a Intf) {
// Here, a is A or B
}
You have to be careful about whether you're dealing with copies, or pointers. For instance:
a:=A{}
b:=B{}
x:=[]Intf{&a,&b}
f(x)
is different from:
x:=[]Intf{a,b}
f(x)
With the first one, if f modified the array elements, the variables a and b are modified because the interface contains a pointer. With the second one, if f modifies the array elements, a and b are not affected because the interfaces in the array contain pointers to copies of those variables.
If, say, A has a method included in the interface Intf that takes a pointer receiver, then you have to use the address of all A instances in the array.
Go's type system is explicit, and strict. So, for instance, you implemented your polymorphic list via interfaces, and you have functions:
func f(input []Intf) {
}
func g(input Intf) {
}
And let's say you have these variables:
var a []A
var b A
where A implements Intf. Then:
g(b) // This is valid
f(a) // This is *not* valid
This is because f gets a []Intf, but a is an []A, not []Intf. To call f, you have to build a []Intf:
fInput:=make([]Intf,0,len(a))
for _,x:=range a {
fInput=append(fInput,x)
}
f(fInput)
So if you're dealing with polymorphic lists, then it makes sense to always work with the interface list, not the concrete type list.
You can also work with type assertions if you need direct access to fields depending on type:
func f(in []Intf) {
for _,x:=range in {
if a, ok:=x.(*A); ok {
a.Field=1
}
}
}

Possibility of having "dynamically-binded" and "implicit" interface?

Is there any construct that allows all classes which implemented a set of functions to be considered as a certain interface, even when the classes themselves do not explicitly implement the interface?
To make the question clearer, I'll make an example. Suppose we want to implement LinearSearch, which look through the whole array and search for certain key, and return the index of the key upon discovery. Essentially, the psudeocode might look something like this:
LinearSearch(A, key)
for (k = 0; k < A.length(); k++)
if (A.get(k) == key)
return k
return NULL
In that case, any classes which implemented length and get will be able to search through the structure. We could implement this on DynamicArray, which acts the same as ArrayList in Java. We could implement this on a LinkedList, ignoring the fact the get takes linear time per query. Similarly for other structures that implement these 2 functions. However, such classes might not have explicitly implemented a common interface, even though it is favorable to have them being in one.
While writing this question, I feel a sense of insecurity tinkering within me about such a construct, but I cannot put it into words. So, is there any reason you think that this might not be a good construct in actual languages?
It's called "duck typing". Message-based object models like Smalltalk allow sending any message to an object as long as its name and parameters match.
In languages like C++, you can emulate this using "signals" and "slots", which, at their most primitive, can be implemented by writing a little template adapter class like
class CallGetLengthAdapterBase
{
public:
int length() = 0;
key_type key() = 0;
};
template<class N>
class CallGetLengthAdapter : public CallGetLengthAdapterBase
{
public:
CallGetLengthAdapter( N* obj ) { mObject = obj; };
int length() { return mObject->length(); };
key_type key() { return mObject->key(); };
protected:
N* mObject;
};
So the LinearSearch would just know about CallGetLengthAdapterBase, and would take a pointer to an object of this type. Whoever owns and connects both of these objects would call them like:
LinearSearch( CallGetLengthAdapter<A_type>(&A), key );
That's all.
From Wikipedia:
Go has "interface" types that are compatible with any type that supports a given set of methods (the type does not need to explicitly implement the interface). The empty interface, interface{}, is compatible with all types.
It sounds like this is what you mean, so it is another sense of interface than we might be used to from Java or such. This is a structural typing kind of interface, where the structure of methods involved are the important part, not a name given to the interface.
More formally, it seems that this is called a type class.

OOP , object concept

According to the standard definition, an object is an entity that contains both data and behaviour.
According to my understanding the data is sent from outside.For eg,we have a class that computes the square of a number.We create an instance and sends a message,along with the number, to the object to compute the square,.
Are we not sending the data from outside?
Why do all the definitions state that the object contains the data?
Thanks
Data, in this context, is state of the object. The definition says that the state/data of object should be internally stored. For example, consider the following class:
class Math {
Double square(double x) {
return x * x;
}
// other similar functions
}
As a language construct, it is a class. But, it is not a true class in object-oriented sense. Because it does not have a state or data. It is just a function wrapped in a class construct. This is not necessarily wrong. Because in this case, it happens that you have operations that don't need a state.
What the definition trying to emphasize is that: you have a real object, when it (or it's class) has both data and behavior. Not every usage of the class construct represents a true object.
Therefore, you have an object if the class representing it satisfies the following three conditions.
The class has state/date. If not, then it is just a bunch of functions. It is not object-oriented, it is procedural.
The class has behavior. If not, then it is just a container, a bunch of variable ( Structures in C).
Not only the class has state/data and behavior/methods, but there is an intrinsic relation between the data and behavior. Which means that just throwing some variables and functions together does not make a true object. For example, if you have state/data and you also have some method, in the class, but if that function does not need to operate upon any of the state, then there is a question whether that method really belongs to that class.
Below is a simple example of what I think is a proper class (representation of object).
Class Patient {
// blood pressure
double systolic;
double diastolic;
double weight;
int age;
public Patient(double systolic, double diastolic, double weight, int age){
}
Public boolean isHealthy(){
// do some calculations and algorithms on age, weight and blood pressure indicators.
// return result as true of false
}
}
Here, we see that class has both state and behavior. We also see that both state and behavior really belong to this class. They are properties of the concept of patient. We further see that operation has an intrinsic relation to data. You can’t decide whether the patient is healthy or not, without consulting/using its state.
I think the problem is with your example which badly fit with an Object Oriented design. I just mean that computing the square of a number is a memoryless function thus there is obviously no reason to store data inside the object properties. However when you will have to deal with the management of stateful entities you will get more easily the importance of classes and object orientation in general.
Your example is a private case where the object doesn't need to hold data (i.e. state). In this case it can be replaced with a function (just the behavior). Most objects need to store data. E.g., an object Person should contain the qualities describing the person, not just possible behavior.
An object is an instance of a class.
Class (a, a*a) is square class but (2, 4) is an instance of it (object). Yes, data is sent to the class and creates new object.

Should private functions modify field variable, or use a return value?

I'm often running into the same trail of thought when I'm creating private methods, which application is to modify (usually initialize) an existing variable in scope of the class.
I can't decide which of the following two methods I prefer.
Lets say we have a class Test with a field variable x. Let it be an integer. How do you usually modify / initialize x ?
a) Modifying the field directly
private void initX(){
// Do something to determine x. Here its very simple.
x = 60;
}
b) Using a return value
private int initX(){
// Do something to determine x. Here its very simple.
return 60;
}
And in the constructor:
public Test(){
// a)
initX();
// b)
x = initX();
}
I like that its clear in b) which variable we are dealing with. But on the other hand, a) seems sufficient most of the time - the function name implies perfectly well what we are doing!
Which one do you prefer and why?
Thank for your answers guys! I'll make this a community wiki as I realize that there is no correct answer to this.
I usually prefer b), only I pick a different name, like computeX() in this case. A few reasons for why:
if I declare computeX() as protected, there is a simple way for a subclass to influent how it works, yet x itself can remain a private field;
I like to declare fields final if that's what they are; in this case a) is not an option since initialization has to happen in compiler (this is Java-specific, but your examples all look Java as well).
That said, I don't have a strong preference between the two methods. For instance, if I need to initialize several related fields at once, I will usually pick option a). That, though, only if I cannot or don't want for some reason, to initialize directly in constructor.
For initialization I prefer constructor initialization if it's possible,
public Test():x(val){...}, or write initialization code in the constructor body. Constructor is the best place to initialize all the fields (actually, it is the purpose of constructor). I'd use private initX() approach only if initialization code for X is too long (just for readability) and call this function from constructor. private int initX() in my opinion has nothing to do with initialization(unless you implement lazy initialization,but in this case it should return &int or const &int) , it is an accessor.
I would prefer option b), because you can make it a const function in languages that support it.
With option a), there is a temptation for new, lazy or just time-stressed developers to start adding little extra tasks into the initX method, instead of creating a new one.
Also, in b), you can remove initX() from the class definition, so consumers of the object don't even have to know it's there. For example, in C++.
In the header:
class Test {
private: int X;
public: Test();
...
}
In the CPP file:
static int initX() { return 60; }
Test::Test() {
X = initX();
}
Removing the init functions from the header file simplifies the class for the people that have to use it.
Neither?
I prefer to initialize in the constructor and only extract out an initialization method if I need a lot of fields initialized and/or need the ability to re-initialize at another point in the life time of an instance (without going through a destruct/construct).
More importantly, what does 60 mean?
If it is a meaningful value, make it a const with a meaningful name: NUMBER_OF_XXXXX, MINUTES_PER_HOUR, FIVE_DOZEN_APPLES, SPEED_LIMIT, ... regardless of how and where you subsequently use it (constructor, init method or getter function).
Making it a named constant makes the value re-useable in and of itself. And using a const is much more "findable", especially for more ubiquitous values (like 1 or -1) then using the actual value.
Only when you want to tie this const value to a specific class would it make sense to me to create a class const or var, or - it the language does not support those - a getter class function.
Another reason to make it a (virtual) getter function would be if descendant classes need the ability to start with a different initial value.
Edit (in response to comments):
For initializations that involve complex calculations I would also extract out a method to do the calculation. The choice of making that method a procedure that directly modifies the field value (a) or a function that returns the value it should be given (b), would be driven by the question whether or not the calculation would be needed at other times than "just the constructor".
If only needed at initialization in the constructor, I would prefer method (a).
If the calculation needs to be done at other times as well, I would opt for method (b) as it also makes it possible to assign the outcome to some other field or local variable and so can be used by descendants or other users of the class without affecting the inner state of the instance.
Actually only a) method behaves as expected (by analyzing method name). Method b) should be named 'return60' in your example or 'getXValue' in some more complicated one.
Both options are correct in my opinion. It all depeneds what was your intention when certain design was choosen. If your method has to do initialization only I would prefer a) beacuse it is simplier. In case x value is also used for something else somewhere in logic using b) option might lead to more consistent code.
You should also always write method names clearly and make those names corresponding with actual logic. (in this case method b) has confusing name).
#Frederik, if you use option b) and you have a LOT of field variables, the constructor will become a quite unwieldy block of code. Sometimes you just can't help but have lots and lots of member variables in a class (example: it's a domain object and it's data comes straight from a very wide table in the database). The most pragmatic approach would be to modularize the code as you need to.