How to defind the relationship between classes in java? - java

More specific about the question:
//There're two classes A and B:
Class A {
public static List<B> b = new ArrayList<B>();
}
Class B {
}
In my schema, I want to an object b from Class B. Then under all circumstances,object b will involve at least two objects "a_x" and "a_y" from Class A. How can I create such a relationship?

First thing,This public static List<B> b = new List<B>(); wont compile.
You might need public static List<B> b = new ArrayList<B>();
You cannot instantiate an Interface.So provide an concreate implementation.Ex:ArrayList
And second thing,You should add them directly where ever your are creating this list.

This is the relationship:
class A
{
public List<B> b = new ArrayList<B>();
}
class B
{
A ax;
A ay;
B(A ax, A ay)
{
this.ax = ax;
this.ay = ay;
}
}
This is what you need?
Why do you need such relantioship?

If you have a relation where each B is related to at least two A instances, then B needs a collection-typed field. For example:
public class B {
private List<A> relatedAList = new ArrayList<>();
...
}
This needs to be an instance field, not a static field.
But if you have a 2+ relationship, it doesn't make sense to call the related objects x and y ... because what if there is a z, and a p and so on. Unless there is a fixed upper bound on the number of related A objects for each B, you have to use some kind of collection to represent each B's related As.

Related

How can I cast objects that don't inherit each other?

I have 2 different classes with different fields and a class which has all the fields of both classes. Is there any way to cast the object in to two separate objects?
class A{
private int a;
private int b;
}
class B{
private int a;
private int b;
}
If object D have all the properties of A and B classes, Is there any way to cast them separately?
Casting take place from child to parent (downcast) or vise versa (upcast):
class A extends B
B b = (B)(new A());
or in case of interfaces:
List<String> myList = new ArrayList<>();
ArrayList<String> myArrayList = (ArrayList)myList;
Be careful when casting - if casting is not possible, you'll receive Exception!
In your case, mapping is what you're looking for. You simply need a mapper.
For example:
public class AToBMapper {
public static A fromB(B b) {
A a = new A();
a.setA(b.getA());
a.setB(b.getB());
return a;
}
public static B fromA(A a) {
//fill in
}
}
As complement of the very good answer of xenteros, you could also use library to do it if you have to repeat this task for many classes.
Spring, apache-commons and many others provides utility class to copy field by field which one of them that have the same name and type between two classes:
For example with ModelMapper :
ModelMapper mapper = new ModelMapper();
A a = new A(....);
B b = mapper.map(a, B.class)
Some libraries are very efficient (Selma, MapStruct, JMapper). Most of them generating the code at compile time
Others are less efficient.
You should so evaluate this point, the size of objects to map and the mapping frequency before generalizing the use of this kind of library.

I have some issue about casting in java

public class A {
private String superStr;
public String getSuperStr() {
return superStr;
}
public void setSuperStr(String superStr) {
this.superStr = superStr;
}
}
public class B extends A {
private String subStr;
public String getSubStr() {
return subStr;
}
public void setSubStr(String subStr) {
this.subStr = subStr;
}
}
And I expect result likes below
public static void main(String[] args) {
A a = fuc();
B b = new B();
b = (B) a;
b.setSubStr("subStr");
System.out.println(a.getSuperStr() + b.getSubStr());
}
private static A fuc() {
A a = new A();
a.setSuperStr("super");
return a;
}
but java.lang.ClassCastException is ocuured.
How can I cast this?
I want use subclass variable and super class variable.
thank you
How can I cast this?
You can't. You can only cast when the object in question has an "is a" relationship with the type. In your case, you have an A object (the one from fn), which is not a B. (All B objects are As, because B extends A, but not all A objects are Bs.)
Consider: Let's call B Bird and A Animal: A Bird is an Animal, but not all Animals are Birds. So we can treat all Birds as Animals, but we cannot treat all Animals as Birds. When you're using a variable of a given type to refer to an object, you're treating the object as being of that type (e.g., B b = (B)a tries to treat the Animal a as a Bird).
Side note: There's no point to the indicated part of the code:
B b = new B();
// ^^^^^^^^^^
b = (B) a;
Since the very next line assigns to b (well, it would if it would compile), there's no purpose served by doing new B() and assigning that to b just beforehand. (Unless the B constructor has side-effects, which is generally a Bad Idea™.)
Casting a particular object to another types does not magically convert it into an instance of that class (or at least not in Java); Therefore, the object referenced by variable a does not e.g. have the field subStr to use despite that the object referenced by b after executing B b = new B(); does.
The others have already explained why you can't do that. I'm here to give you a simple alternative. Your B class could have a constructor that had an A as argument and you would simply wrap that A so you could "transform" it to a B. Using that your code would look way more clean, it would actually work and you were following a good design pattern. For more information check the Decorator Pattern

Can a class have a "IS A Relationship" with itself?

class A
{
}
class B extend A
{
int i;
int j;
}
Can a class have an IS-A Relationship with itself?
In this question, B is an A, right?
But can class B have an IS-A relationship with class B?
It's an identity (and tautology) - an object of type B will always be able to describe itself as an object of type B.
The further extensions of the is-a relationship pertain to hierarchies of inheritance; that is to say, since B extends A, B is-an A. This allows you to write the following expression:
A anA = new B();
But B is a B too. It hasn't lost that part of its identity because it now inherits from another class.

Why B b = new A() is invalid and A a = new B() is valid when B extends A?

I am new to JAVA and want to know that why
A a = new B();
is valid
and
B b = new A();
is invalid
Considering that:
class A;
class B extends A;
Because B, by extending A, is also an A. We say this in object-orientation terms by saying that a B is-a A. This means that you can use a B anywhere you use an A.
This relationship is not commutative -- B is-a A does not imply that A is-a B. Therefore you cannot use an A anywhere you would use a B.
Consider this case:
class Animal;
class Dog extends Animal;
This makes sense:
Animal animal = new Dog();
Anywhere it makes sense to use an Animal you can also use a Dog. This is intuitive.
Dog dog = new Animal();
This, on the other hand, does not make sense.
Because when B extends A you consider that every B is a more complex A, using the attributes and methods from A and adding some of his own, but an A cannot be a B, there could be methods in B not specified in A, and as it is not extended from B, cannot be instantiated.
Every B is an A , but no every A is a B ( unless you specify that )
class A {
int i = 10;
}
class B {
int i = 10;
int j = 20;
}
class C {
public static void main(String args[]){
B b;
B b=new A();
System.out.println(b.j);
}
}

Put inside the extended class the parent class

I have a problem with an extended class.
This are the classes:
class A{
}
class B extends A{
}
Now the problem is that I have a method that returns A , something like this:
public A doSomthing(){
}
And now I try to do something like this:
public static void main(){
B b = new B();
b = doSomething();
}
But it doesn't seem to work. Is there any way to solve this problem?
The only thing I thought about is it to have something like this:
class B extends A{
public B(A a){
copy all the fields from A to B}
}
And then do:
A a = new A();
a = doSomthing();
B b = new B(a);
Is there a better option?
Fundamentally I think you've missed what the assignment operator does. This statement:
b = doSomething();
changes the value of b to whatever the doSomething() method returns. It doesn't depend on the existing value of b at all. So similarly, when you have:
A a = new A();
a = doSomthing();
... it would make more sense to write:
A a = doSomething();
Now if you need to create an instance of B based on an instance of A, then it may well make sense to write:
A a = doSomething();
B b = new B(a);
or just:
B b = new B(doSomething());
... but you need to understand when existing values are used and when they're not.
Usually I find that when I need to do something like that, it's actually better to use composition than inheritance anyway - that B should have a reference to an existing A rather than extending A. That's certainly something to consider, but without a concrete example we can't say for sure.
You instantiate your object b to be of Type B instead of A therefore polymorphism would not work when calling doSomthing
Change your object b to be of Type A
Java does not have multiple inheritance (c# example) to enforce method signatures. Instead it would make sense to
public static A doSomthing(){
A result = new A();
...
return result;
}
Then you can use:
A a = A.DoSomthing();
B b = (B)A.DoSomthing();

Categories