So I have the following classes:
class A{
public A(int n1){
n=n1;
}
int n;
}
class B extends A{
public B(int n2){
super(n2);
cnt=1;
}
int cnt;
}
class C extends B{
public C(int n3){
super(n3);
clr="red";
}
String clr;
}
public class Driver {
public static void main(String[] args){
A a,b,c,d,e;
a=new B(200); d=a.copy();
b=new C(100); e=b.copy();
}
}
I am asked to define the method copy() in classes A,B,C. The copy method essentially makes a copy of all nested objects.
I have 2 questions:
I don't see any nested objects being constructed, why does he ask me to make a copy of all nested objects? Is it because when I construct a subclass object, a base class object is constructed and nests inside the subclass object?
Is it correct to write the method as follows (take class B for example):
class B extends A{
public B(int n2){
super(n2);
cnt=1;
}
int cnt;
public A copy(){
A copy_ref=new B(1);
((B)copy_ref).cnt=this.cnt;
copy_ref.n=super.n;
return copy_ref;
}
}
I think you are confusing to different concepts.
You are confusing the has-a relationship with the is-a relationship.
In your code C is a B and also an A: C has an is-a relationship with B and A.
C does not contain an instance of B or A (that would be an has-a relationship).
Since C is an B and A, it contains all the members of B and A. Calling a copy of C will copy all of its members variables. You do not need to create any particular method, you can just use the already defined Object.clone method.
If you want to define your own clone/copy method I suggest you look at the following article on the subject.
Enjoy !
Related
I have a model:
class A {
int a;
int b;
int c;
}
I want to create a new class like:
class B {
int a;
int b;
}
I don't want to rewrite all attributes in class B, these attributes are already written in A. How to use A to create B.
We can add extra features to class with extends but how do we create less specific class? Are there any patterns for this? How should class A or class B be designed to be more polymorphic?
(I want to use class B for inserting into a database, the model class and database table should be same)
There should be an "IS A" relation between parent and derived classes.
I.e. the derived class (B) should also be an instance of it's parent class (A).
If you remove something from B it can't be A anymore.
Therefore it should not be possible.
Not sure whether you are able to change the classes/implementation but there seem to be multiple solutions. First one would be to have class A extend class B
public class B {
int a;
int b;
}
public class A extends B {
int c;
}
but that is not answering your core question (creating less specif class).
Creating a less specific class (or at least something that mimics it) could be done via interfaces and getter/setters, so for example:
public class Implementation implements A,B {
private int a;
private int b;
private int c;
public int getA(){return a;}
public int getB(){return b;}
public int getC(){return c;}
...
}
public interface A {
int getA();
int getB();
int getC();
}
public interface B {
int getA();
int getB();
}
I guess you need a design technique like composition.
Explanation : If you want use class B in class A, you can use B b = new B(); in your class A ! this is composition.
also you can implement interfaces instead of class which provides you multiple inheritance.
here in syntax :
class A implements interface1, interface2
I am trying to implement and access a new data members and a new member function in concrete class other than the one inherited from parent class. But can not do that.
Real Question is as follows:
Create an abstract class A with 2 data members and 2 member functions.
Create two concrete classes of the A class, named as B and C. Each concrete class should have 2 new data members and 2 new member functions. The data members and member functions in the 2 classes should not be the same. Write main() methods that create objects of each subclass, and send them enough messages to show the methods work.
Please help.
The code is --
import java.util.*;
abstract class A
{
abstract void display();
abstract void rules();
int players;
int length;
}
class B extends A
{
B(int a,int b)
{
players=a;
length=b;
}
void rules()
{
System.out.println("B rules");
}
void display()
{
System.out.println("In B players=" +players);
}
}
class C extends A
{
C(int a,int b)
{
players = a;
length = b;
}
void summary()// PROBLEM IS HERE . CAN NOT ACCESS summary
{
System.out.println("rules");
}
void display()
{
System.out.println("In C players=" +players + " length=" +length);
}
}
public class BatandBall
{
public static void main(String args[])
{
System.out.println("Airtel Champions League");
A obj = new B(10,3);
obj.display();
A obj1 = new C(11,8);
obj1.display();
obj1.summary(); // PROBLEM IS HERE . CAN NOT ACCESS summary
}
}
You cannot access it because the variable you created is of type A, not C. I know that actually obj1 is C but polymorphism makes it not C. As you can see, you are declaring an A here:
A obj1;
No matter what values you put in obj1, it is still of type A. So how do you call summary? You need a cast! This will change obj1's type to C:
(C)obj1
And then you can just use this to call summary:
((C)obj1).summary();
That's easy isn't it?
And by the way, your C class doesn't implement rules as defined in A. You should probably implement that or your code won't compile.
I have three classes A,B and C.
I have created object of class A in class B and I have inherit class B to class C.
Do the object of class A also inherit to class C?
Can I access member functions of class A through class C?
You have used composition between A and B (B encloses an instance of A) and inheritance between B and C. So from C you can "get at" methods in B by using the super keyword. You may (depending on scope) thus also access members of A from within C, but you are not doing it directly by inheritance, as would be the case if C inherits from B and B inherits from A.
Here is a small example for your case use it,
class A
{
String varOfA="Class A";
private String locOfA="Local variable";
}
class B extends A
{
int number=20;
}
class C extends B
{
int total=number;
void show()
{
System.out.println(super.varOfA);
//System.out.println(super.locOfA); //This is a private variable variable, so it
//won't be accessed from sub class
System.out.println(total);
}
}
public class MLInhert
{
public static void main(String args[])
{
C obj=new C();
obj.show();
}
}
Please let me know if i made any mistake in this answer. Because i'm a beginner here.
Depending on the access specifiers of the variables in the class it is decided which class level variable can be accessed. See the table below:
For more info refer : http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html
I have a number of classes, please allow me to introduce them and then ask my question at the end:
I have a container class which contains two objects in a composite relationship:
public class Container{
A a;
B b;
public someMethod(){
a.getC().myMethod(b);
}
}
A and B are superclasses (or Interfaces), with subtypes that can also be the type held in the composite relationship.
A contains a member of (interface) type C:
public class A{
C c;
}
public interface C{
public void myMethod(B b);
}
public class D implements C{
public void myMethod(B b){
//This code will modify the state of object b, in class Container.
b.changeState();
}
}
public class E implements C{
public void myMethod(B b){
//This code will modify the state of object b, in class Container.
b.changeState();
}
}
My problem is that I wish to modify the state of object b from a method starting in the container class, which eventually calls code down the hierarchy, to classes D and E- calling myMethod() via dynamic binding. I want to do this because I am going to use polymorphism to run the correct myMethod() (depending on whether the type of object is D or E) and I wish to do this, rather than write IF statements.
So my problem is that it seems very bad continually passing the instance of object b down the class hierarchy to myMethod, so that I can run b-specific code to modify the state of b. Is there anything else I can do to modify b from d and e (collectively known as c)?
I can get this to work using just interfaces but without using generics- but when I added generics i had problems with types and that made me start to think if my whole design was flawed?
EDIT: I could probably do this easily just by using IF statements- but I wanted an elegant solution using polymorphism of classes D and E.
First of all, if I understood your question correctly, no instance of B is being "passed down" in your code. Dynamic dispatch will simply cause the myMethod() implementation in the actual type of a to be called with an instance of B as argument.
While it may be tedious to have to write the argument explicitly every time you implement myMethod(), there's nothing wrong with it.
The alternative is to give each subclass/implementation of A an attribute of type B. In this case, however, you would have to pass your B instance down the chain of constructors to the class that actually has your B attribute.
Your code would become:
public class A{
C c;
public A(C c) {
this.c = c;
}
public interface C{
public void myMethod(B b);
}
public abstract class CC {
protected B b;
public CC(B b) {
this.b = b;
public class D extends CC implements C {
public D(B b) {
super(b);
}
public void myMethod(){
b.changeState();
}
}
public class E extends CC implements C {
public E(B b) {
super(b);
}
public void myMethod(){
b.changeState();
}
}
And then somewhere, e.g. in Container's constructor:
b = new B();
a = new A(new E(b));
You could pass the instance of B to the constructor of E. (or use a setter). That poses issues in itself, but at least it avoids having to pass B down every time you call myMethod(), which now needs no arguments.
e.g.
somewhere inside B
E myE = new E(this);
and, inside E
final B myB;
public E(B myHigherLevelThing) {
this.myB = myHigherLevelThing;
}
public void myMethod() {
myB.changeState();
}
Use the most general interface for the declarations, I'm a little confused about your full hierarchy so there may be room for improvement there...
Why can't I cast a base class instance to a derived class?
For example, if I have a class B which extends a class C, why can't I do this?
B b=(B)(new C());
or this?
C c=new C();
B b=(B)c;
Alright let me be more specific as to what I'm trying to do. Here's what I have:
public class Base(){
protected BaseNode n;
public void foo(BaseNode x){
n.foo(x);
}
}
public class BaseNode(){
public void foo(BaseNode x){...}
}
Now I want to create a new set of classes which extend Base and Basenode, like this:
public class Derived extends Base(){
public void bar(DerivedNode x){
n.bar(x);//problem is here - n doesn't have bar
}
}
public class DerivedNode extends BaseNode(){
public void bar(BaseNode){
...
}
}
So essentially I want to add new functionality to Base and BaseNode by extending them both, and adding a function to both of them. Furthermore, Base and BaseNode should be able to be used on their own.
I'd really like to do this without generics if possible.
Alright so I ended up figuring it out, partly thanks to Maruice Perry's answer.
In my constructor for Base, n is instantiated as a BaseNode. All I had to do was re-instantiate n as a DerivedNode in my derived class in the constructor, and it works perfectly.
because if B extends C, it means B is a C and not C is a B.
rethink what you are trying to do.
The existing answers are fine in terms of an abstract argument, but I'd like to make a more concrete one. Suppose you could do that. Then this code would have to compile and run:
// Hypothetical code
Object object = new Object();
InputStream stream = (InputStream) object; // No exception allowed?
int firstByte = stream.read();
Where exactly would the implementation of the read method come from? It's abstract in InputStream. Where would it get the data from? It simply isn't appropriate to treat a bare java.lang.Object as an InputStream. It's much better for the cast to throw an exception.
In my experience it's tricky to get "parallel class hierarchies" like the one you're describing to work. You may find that generics help, but it can get hairy very quickly.
You need to use the instanceof keyword to check the type of object referenced by n and typecast the object and call the bar() method. Checkout Derived.bar() method bellow
public class Test{
public static void main(String[] args){
DerivedNode dn = new DerivedNode();
Derived d = new Derived(dn);
d.bar( dn );
}
}
class Base{
protected BaseNode n;
public Base(BaseNode _n){
this.n = _n;
}
public void foo(BaseNode x){
n.foo(x);
}
}
class BaseNode{
public void foo(BaseNode x){
System.out.println( "BaseNode foo" );
}
}
class Derived extends Base{
public Derived(BaseNode n){
super(n);
}
public void bar(DerivedNode x){
if( n instanceof DerivedNode ){
// Type cast to DerivedNode to access bar
((DerivedNode)n).bar(x);
}
else {
// Throw exception or what ever
throw new RuntimeException("Invalid Object Type");
}
}
}
class DerivedNode extends BaseNode{
public void bar(BaseNode b){
System.out.println( "DerivedNode bar" );
}
}
You can create a constructor for B that takes C as a parameter.
See this post for ideas to do what you're trying to do.
Base classes shouldn't know anything about classes derived from them, otherwise the problems highlighted above will arise. Downcasting is a 'code smell', and downcasting in the base class to a derived class is particularly 'smelly'. Such designs can lead to difficult to resolve circular dependencies too.
If you want a base class to make use of derived class implementations use the Template method pattern i.e add a virtual or abstract method in your base class and override and implement it in the derived class. You can then safely call this from the base class.
You can't do that because C does not necessarily implement the behaviours you created when you extended it in B.
So, say C has a method foo(). Then you know that you can call foo() on a B, as B extends C, so you can cast accordingly a treat a B as if it was a C with (C)(new B()).
However - if B has a method bar(), nothing in the subclass relationship says that you can call bar() on C too. Thus you cannot treat a C as if it were a B, and so you cannot cast.
In your exemple, you can cast n into a DerivedNode if you are certain that n is an instance of DerivedNode, or you can use generics:
public class Base<N extends BaseNode> {
protected N n;
public void foo(BaseNode x){
n.foo(x);
}
}
public class BaseNode {
public void foo(BaseNode x){...}
}
public class Derived extends Base<DerivedNode> {
public void bar(DerivedNode x){
n.bar(x); // no problem here - n DOES have bar
}
}
public class DerivedNode extends BaseNode {
public void bar(BaseNode){
...
}
}
Because if B extends C, then B might have stuff that isn't in C (like instance variables you initialize in the constructor that are not in new C())