If we go according to below code
class A;
int a = 10;
endclass
class B extends A;
int b = 20;
endclass
program test;
A a1;
B b1;
initial begin
b1 = new();
a1 = b1; //child class object is assigned to parent class handle
$display("Value of variable b is %x", a1.b);
end
endprogram
Then the above code results into error that "Could not find member 'b' in class 'A'"
Now my observation is that when extended class object is assigned to base class handle then simulator will check the type of handle and check whether variable is present in that class or not. As variable b is not defined in base class then it will result into error.
So I want to confirm whether my above observation is correct or incorrect?
I would welcome if anyone wants to add something to my observation, in case it's correct.
Thanks
You are correct, and it is the intended behavior in OOP languages I know (I don't especially know the one you are using, but your example is simple enough). Being able to use a variable declared by a child class would result in a violation of the object oriented principle of polymorphism (or subtyping).
I will answer you in Java, because I'm sure of the syntax in this language for the example i want to give. Imagine two variables with the same declared type :
public A buildA () {
return new B();
}
public static void main () {
A a1 = new A();
A b1 = buildA();
}
The polymorphism principle is that a1 and b1 should implement the same interface and be used indifferently. If I was allowed to access a variable's member b, since the compiler couldn't guess which is base and which is child, then it would allow the program to crash at runtime every time I access a concrete A, removing the safety net types are supposed to provide.
I would not use the terms parent and child class here. It implies you have two separate class objects.
What you describe is two different class types where one type is derived/extended from a base type. Then you declare two class variables: a1 and b1. These variables may hold a handle to class object of the same type, or a handle to an object of any type extended the type of the variable. However, the compiler will not let you reference any variable or member that has not been defined by type of the class variable regardless of the type of the object the class variable currently hold a handle to.
OOP gives you the ability to interact with a class variable with the possibility of it having a handle to much more complex object without you knowing what extensions have been made to that object. But you have to assume that the object could be the same type as the class variable. The compiler enforces this as well. If you want to interact with the extended class variables, you need to use an extended class variable type.
Related
I am new to OOP. I am still in a learning phase.
Why do we need constructors, When we can initialize the values of the properties (variables) by writing a "Initialize function"?
Basically why do we write a constructor when we can achieve the same results even by writing a function for initializing the variables?
The constructor IS the "Initialize function"
Rather than calling two functions
object = new Class;
object.initialize();
You just call
object = new Class();
The logic inside the constructor can be identical to the logic inside the initialize function, but it's much tidier and avoids you naming your function initialize(), me naming mine initialize_variables(), and someone else naming theirs init_vars()... consistency is useful.
If your constructor is very large, you may still wish to split variable initialisation into a separate function and calling that function from your constructor, but that's a specific exception to the scenario.
So answer is simple
Why do we write Constructor?
Because in C you can write,
int i;
if write like this In above case data type and variable defines if you define like this memory allocated for i variable.So simple here we define class name and variable name(object name) we can create memory allocated for class name.
Example
myClass objectName;
But in C++ new keyword is used for dynamic memory allocation, so this dynamic memory which we can allocate to our class but here my example myClass is our class and we want to allocate to dynamic memory allocated.
So
myClass objectName = new myClass();
and simply constructor is memory allocation for class variable is called the constructor.`
the role of the constructor is to initialize the variables/values.it is the "initialization function".The only reason i find on why we use a constructor instead of a normal function to initialize the variables is to stop different people from using different function names and avoid ambiguity and it is much more easier to use a constructor which is instantiated automatically as soon as the class is run,instead of having to write a separate code for instantiation.this may seem small and like something that doesn't require much work,but only for a very small program,for larger ones the struggle is real.
It is usual to put mandatory things into the constructor and optional ones into the Initialise function.
For example, consider an amplifier that requires a power source so that would be supplied to its constructor. Logically, you may want to turn it on and set its power level but one could argue that you might not want to do that until later. In pseudo-code:
class Amplifier
{
public Amplifier(PowerSource powerSource)
{
// create amplifier...
}
public int PowerLevel;
public void Initialise()
{
// turn on...
}
}
The example, above, is rather puerile but it illustrates the concepts at play. It is always an issue of design, however, and opinions do vary.
Some classes of object, however, will have to perform obvious set-up operations during their construction phase. In these cases, the requirement to have a constructor is very easy to understand. For example, if your object might require a variable amount of memory, the constructor would be a logical place to allocate it and the destructor or finaliser would be a logical place to free it up again.
Even if you don't use constructor it will call implicitly by your language translator whenever you create object.Why?
The reason is that it is used for object initialization means the variable(instance) which we declare inside our class get initialized to their default value.
class Person {
//Class have two parts
//1.Data(instance variable)
//2.Methods(Sub-routine)
String name;
int age;
}
public class Stack{
public static void main(String[] args){
Person person1 = new Person();
System.out.println("Name: "+person1.name);
System.out.println("Age: " + person1.age);
}
}
Output- Name: null
Age: 0
"null" and "0" are default values which are impicitly set by default constructor.
When we initialize a class by creating an instance or object the constructor is called automatically. This is very helpful when we need a huge amount of code to be executed every time we create an object.
The best use of constructor can be seen when we create a " graphical user interface". While building a GUI for an application we need to separate the code for designing the GUI and the business logic of the application. In such a case we can write the code for designing GUI, in a constructor and business logic in respective methods. This make the code tidy and neat too.
Also when an object is created the global variables can be initialized to their default values using constructor. If we don't initialize the global variables, then the compiler will do it implicitly by using the default constructor.
So constructor is a very wise concept which appears to be an idiosyncrasy at first but as you code further and more and more you will realize it's importance.
Because constructors are exactly for that: to avoid using an "initialize function"
Plus you can have have as many constructors as you want: you juste feed them some parameters, depending how you want to inialize your object.
Constructor is a special member function which has same name as class name and called whenever object of that class is created. They are used to initialize data field in object.
Constructor has following properties:
It has same name as class name.
It is called whenever object of a class is created.
It does not have return type not even void.
It can have parameters.
Constructor can be overloaded.
Default constructor is automatically created when compiler does not find any constructor in a class.
Parameterized constructor can call default constructor using this() method.
A constructor can be static for static data field initialization.
It is not implicitly inherited.
For More Info
https://en.wikipedia.org/wiki/Constructor_(object-oriented_programming)
Yesterday I was asked a question in an interview:
Suppose class A is a base class, and class B is derived class.
Is it possible to create object of:
class B = new class A?
class A = new class B?
If yes, then what happen?
Objects of type B are guaranteed to also be objects of type A. This type of relationship is called "Is-a," or inheritance, and in OOP it's a standard way of getting polymorphism. For example, if objects of type A have a method foo(), objects of type B must also provide it, but its behavior is allowed to differ.
The reverse is not necessarily true: an object of type A (the base class) won't always be an object of type B (the derived class). Even if it is, this can't be guaranteed at compile-time, so what happens for your first line is that the code will fail to compile.
What the second line does depends on the language, but generally
Using a reference with the base type will restrict you to only accessing only members which the base type is guaranteed to have.
In Java, if member names are "hidden" (A.x exists and so does B.x, but they have different values), when you try to access the member you will get the value which corresponds to the type of the reference rather than the type of the object.
The code in your second example is standard practice when you are more interested in an API than its implementation, and want to make your code as generic as possible. For instance, often in Java one writes things like List<Integer> list = new ArrayList<Integer>(). If you decide to use a linked list implementation later, you will not have to change any code which uses list.
Take a look at this related question: What does Base b2 = new Child(); signify?
Normally, automatic conversions are allowed down the hierarchy, but not up. That is, you can automatically convert a derived class to its base class, but not the reverse. So only your second example is possible. class A = new class B should be ok since the derived class B can be converted to the base class A. But class B = new class A will not work automatically, but may be implemented by supplying an explicit conversion (overloading the constructor).
A is super class and B is a SubClass/Derived Class
the Statement
class A = new class B is always possible and it is called Upcasting because you are going Up in terms of more specific to more General
Example:
Fruit class is a Base Class and Apple Class is Derived
we can that Apple is more specific and must possess all the quality of an Fruit
so you can always do UPcasting where as
DownCasting is not always possible because Apple a=new Fruit();
A fruit can be a Apple or may it is not
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.
If class B inherits from class A, does class B always have to be a sub-type of A when used in inheritance?
I am thinking if it is possible to use inheritance to provide extra code to B, when B is not a subtype of A?
If type A inherits from B, that means two things:
Class `A` will be able to use public and protected static methods from class `B`, without having to specify the class name, and objects of class `A` will implicitly include all public and protected class members from `B` without having to respecify them.
Any code accepting objects of type `B` will, at at compile time, accept objects of type `A`, and objects of class `A` will be able to use class `B`'s public and protected instance methods on themselves.
Interfaces essentially embody concept #2 but not #1 (since interfaces have no static methods, and have no members that can be used implicitly without having to specify them). There is no built-in way to achieve #1 without #2; the only significant benefit of having #1 without #2 would be to save typing.
If:
class B extends A
Than B is by definition a subtype of A.
If you don't want that, you can use PHP's traits, which is basically interfaces with implementation.
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.