Can't reference two classes inside one? - java

I'm utilizing object oriented programming for the first time in Java and haven't had any issues until now.
I have a Customer class (irrelevant details omitted):
public class Customer {
public String bikesOwned;
public Customer() //Default Constructor
{
bikesOwned = "";
}
public Customer(String aBike) //Parameterized Constructor
{
addBike(aBike);
}
public void addBike (String aBike) //Mutator Method for Bikes Owned
{
bikesOwned = aBike;
}
public String toString()
{
String returnBikes = bikesOwned.toString();
return returnBikes;
}
}
And I have a Bike Tester class which uses information from my Bicycle class:
public class bikeTester {
public static void main (String [] args)
{
Bicycle hisBike = new Bicycle(Bicycle.BikeType.Hybrid Bicycle.UserType.Men,
Bicycle.FrameMaterial.Carbon, Bicycle.BrakeType.Caliper,
Bicycle.Condition.Used, 29, 18, 10, "REI", "Black");
Customer don = new Customer();
don.setFirstName("Don");
don.setLastName("Norman");
don.setPhoneNumber("804 123-4567");
don.setEmailAddress("dnorman#aol.com");
don.addBike(hisBike);
System.out.println(don);
System.out.println();
}
My issue is that when I compile, I get this error:
"addBike(java.lang.String) in Customer cannot be applied to (Bicycle)".
I can't figure out why everything else is working except for addBike. Any ideas? Any input is very appreciated.

Your addBike method expects a String parameter:
public void addBike (String aBike)
But you're sending it a Bicycle parameter:
don.addBike(hisBike);
Either send the method a String or change the method to accept a Bicycle (or add another method of the same name which accepts a Bicycle).
It's not entirely clear to me how you would convert between a String and a Bicycle, especially given that the method itself is just setting a value called bikesOwned which itself is a String for some reason. Maybe bikesOwned should be a list or collection of some kind and you want to add items to that collection?
The logic of what you ultimately want this code to do is up to you. But the error itself is pretty straightforward. String and Bicycle are two different things.

The addBike method receives a String parameter but you are sending a Bicycle type to the function. It's basically a type mismatch.
Try sending a Stringvalue to the function.
Or, change the parameter in the addBike method to Bicycle type.

You're trying to pass a "Bicycle" instance from
don.addBike(hisBike);
into a method:
public void addBike (String aBike)
that takes a string parameter.
Either change your method to accept a Bicycle instance (and presumably add it to some array of owned bikes) or if you meant to just pass in the name of the bike for instance, change the call accordingly.

Related

Using variables for creating objects and calling methods in Java

Hi Everyone I am beginner in java and came across a question like Can I use variables for creating objects and calling methods to reuse the code.
Tesla.java
public class Tesla extends Car {
#Override
public void buy(){
System.out.println("Tesla bought");
}
#Override
public void sell(){
System.out.println("Tesla Sold");
}
}
Ford.java
public class Ford extends Car {
#Override
public void buy(){
System.out.println("Ford bought");
}
#Override
public void sell(){
System.out.println("Ford Sold");
}
}
Car.java
public class Car {
public static void main(String[] args) {
String[][] arr = {{"Tesla, Buy"},{"Ford", "Sell"},{"Benz", "Sell"}};
Car car = new Tesla();
car.buy();
Car car = new Ford();
car.sell();
}
public void buy() {
System.out.println("Car bought");
}
public void sell() {
System.out.println("Car Sold");
}
}
Here instead of creating each object I just want to use one for loop and create respective object and respective method based on the array elements.
Logic like below.
public static void main(String[] args) {
String[][] arr = {{"Tesla, Buy"},{"Ford", "Sell"},{"Benz", "Sell"}};
for(int i = 0;i<arr.length-1;i++){
Car car = new arr[i][0]();
car.arr[i][1];
}
}
How to achieve above logic? Is this something achievable in Java? I searched in google couldn't find relevant questions or problems. Please help me. Thanks in advance.
Note:- I don't want a workaround I just want to know the if logic is achievable using any advanced java concepts I am unaware of.
If you want to instantiate objects of various subclasses according to string inputs, you have at least two options:
Reflection
Builder pattern
Reflection
As commented by Nikolaus, one route is to use Java’s reflection facility. This is the “magic” way, where you would find at runtime the name of the class matching your string input. For example, "Tesla" string would lead you to loading an object of type Class representing the Tesla class you wrote at compile time. You would call methods on that Class object to create an instance of your subclass. In other words, you are programmatically doing a roundabout replacement for the code new Tesla(…).
I do not recommend going the reflection route. This is not “normal” Java app programming. Reflection is usually done only in certain kinds of frameworks and in special rare circumstances.
Builder pattern
The other route more commonly used is the Builder pattern. You define another class called something like CarBuilder. You pass your text values into one or more methods of an object of this type CarBuilder. Those methods validate the inputs.
When done setting up the various pieces of input, you eventually call a method conventionally called build. That method produces and returns an object of type Car. That Car object is actually from a subclass, is actually a Tesla or Ford.
CarBuilder builder = new CarBuilder() ;
builder.setBrand( "Tesla" ) ;
builder.set… = … ;
…
Car car = builder.build() ; // Actually a `Tesla` subclass object.
Rather than create different classes (Tesla, Ford) that inherit from a superclass (Car), just pass in parameters to your Car class methods:
public class Car {
public void Buy(String brand) {
System.out.println(brand+" bought");
}
public void Sell(String brand) {
System.out.println(brand+" Sold");
}
}
I would also move the main method out to a separate Runner class. Its only responsibility would be to run the program and nothing else. That way you decouple the classes that implement your model (Car...) from the classes used to run the program.
Additionally, my example is a bit weak in the sense that I have to pass in the brand for each method. What you should do instead is introduce the notion of a constructor in your Car class and the notion of a class attribute. Your code then becomes
public Class Car{
private String brand;
public Car(String brand){
this.brand = brand;
}
public void Buy(String brand) {
System.out.println(brand+" bought");
}
public void Sell(String brand) {
System.out.println(brand+" Sold");
}
}
One last thing: methods typically don't start with a capital letter in Java so you should rename Buy and Sell to buy and sell.
Your second requirement is also to parameterize the action (buy or sell). You can apply the same principle i.e. have a generic method (doAction()) that will now take in 2 parameters: the car brand and the action you want to do. But IMHO that's pushing it too far and losing value.

How to return an object from different classes in Java?

I'm beginner in Java and I need help. I have several classes.
public class A{
private String name = "A";
public String getClassName(){
return "A";
}
public void editClassName(String name){
this.name = name;
}
}
public class B{
private String name = "B";
private int counter = 0;
public String showClassName(){
return "B";
}
public int getCount(){
return counter;
}
}
Such classes could be more. I also need to have some class witch can return an instance of asked class.
public class ClassSelector{
public static ??? getClassByName(String nameOfClass){
if(nameOfClass == "A"){ return new A();}
if(nameOfClass == "B"){ return new B();}
}
}
And here is a code that I want to use to get access to appropriate class:
ClassSelector.getClassByName("A").getClassName();
ClassSelector.getClassByName("B").showClassName();
I need to have an access to the instance of the class, and each instance can show it's unit methods that class has.
In this situation I don't get which return type I should use in the 'getClassByName' method.
I will very appreciate for help.
I would very much like to offer an alternative architecture if possible! It's not much different to what you have.
Firstly, we'll define some interface.
public interface Named {
String getName();
}
Now, this means you can have lots of concrete classes but provided they implement this interface, you'll know (and the Java compiler will know) that they have the getName method available to you.
Next, let's update your class to implement this interface.
public class A implements Named {
public String getName() {
return "A";
}
}
You could do this for classes B, C... and so on.
Now your method return type can be set to Named, that is:
public class ClassSelector{
public static Named getClassByName(String nameOfClass){
if(nameOfClass.equals("A")){ return new A();}
if(nameOfClass.equals("B")){ return new B();}
}
}
And you can access the response like so:
Named response = ClassSelector.getClassByName("A").getName();
As Eran suggested, it can be only of type Object, because they don't have a common superclass other than Object. If you don't want to work with Object class, you can create a body-less interface and implement it in both(or multiple classes) and that can be your return type.
After the call of the method, you can find the specific type of the returned object with instanceof;
What you are trying to do is called the Factory Pattern.
Assuming you are crating Widgets I suggest;
Introduce a Widget interface and have A and B implement Widget as per Christopher’s answer
Rename ClassSelector to WidgetFactory
Rename the method getClassByName to create, make it non-static and return Widget instances
This is more aligned with common Java name conventions and thus makes your code readily understandable by most developers.
If you want to keep your factory static it is of course possible but it may make your code less testable as it cannot be switched out for another factory in your tests. This is problematic if A and B are heavy weight objects that carries a lot of external dependencies that you may want to exclude.
If testability is a concern you may even consider making the factory implement a WidgetFactory interface...
First of all, please note that for string comparison you have not to use "==" (the problem is in nameOfClass == "A" and so on, I say it only for completeness).
I want suggest a solution based on reflection, that maybe could be more concise:
public interface IClass {
}
public class A implements IClass {
private String name = "A";
}
public class B implements IClass {
private String name = "B";
}
public class ClassSelector {
public static void main(String[] args) {
IClass obj = null;
try {
Class c = Class.forName("A");
obj = (IClass) c.newInstance();
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
System.out.println("Create object of type " + obj.getClass());
}
}
Thanks to all guys, who have answered my. Forgive me, when I create the first post, I made one mistake, which leads to misunderstanding what I mean. Now the code in the first post is better to show what I'm looking for.

Accessing Objects from ArrayLists

I have an arraylist of objects that I am sending from class "Testing" to class "Subjects", but can't access some of the methods in the Subjects class.
I would like to be able to simply send an arraylist of "Subject" objects (from the Testing class) to a method in the Subject class and be able to use other methods within the Subject class.
public class Subject {
private String subjectName;
private String courseCode;
//getters and setters for subjectName and courseCode
I can access the following method if I just call it from the Subject class, but not from the Testing class.
public String getDiscipline(){
int a = courseCode.length()-3;
String discipline = courseCode.substring(0, a);
return discipline;
}
In the method below, I can return and print objects and call the method I want, but only for one object...
public List<?> allDisciplines(ArrayList<?> inputSubjects){
for (int i = 0; i<inputSubjects.size(); i++){
System.out.println(inputSubjects.get(i)); //this returns all the
//objects, but why won't this work instead?: inputSubjects.get(i).getDiscipline();
}
//initialise new arraylist
List<String> dis = new ArrayList<>();
dis.add(getDiscipline()); //This works, but only for whatever single
//object I used to call the allDisciplines
//method with
//
return dis;
}
In another class , I pass the object array "subjects" into the allDisciplines method of the Subject class.
public class Testing {
public static void main(String[] args) {
// TODO code application logic here
Testing program = new Testing();
program.start();
}
public void start(){
//gets the data from a file, converts it into "Subject" objects with
//subjectName and courseCode
The following works because it's only sending one object through and I only get one result.
subjects.get(3).allDisciplines(subjects);
But if I try to access the allDisciplines method from the Testing class, I can't because it's not static and if I make the class static, it needs the private ints to be static which then don't change between iterations of my loops and I end up with the same value for fields.
allDisciplines(subjects); //does not work - can't see the allDisciplines
//method
I am not sure whether the problem is because I can't access the method outside of its class or because I am not properly referencing the objects in the arraylist.
Thanks for any help you can give me - I am quite confused!
I think the problem is the allDisciplines method. It should be static. You seem to not quite understand generics. I rewrote it for you:
public static List<String> allDisciplines(ArrayList<Subject> inputSubjects){
//initialise new arraylist
List<String> dis = new ArrayList<>();
for (Subject subject : inputSubjects) {
dis.add(subject.getDiscipline());
}
return dis;
}
I looped through the subjects passed in and added the discipline of each to a new array list and returned it. I also changed List<?> to List<Subject> because we are expecting the client code to pass a list of subjects.
Another shorter way to implement this:
public static List<String> allDisciplines(ArrayList<Subject> inputSubjects){
return inputSubjects.stream().map(Subject::getDiscipline).collect(Collectors.toList());
}
Now you can call allDisciplines by
Subject.allDisplines(subjects)
in Testing.

In java when an object calls its method, I want the "Reference Variable" name in the running method

I want to retrieve the reference variable name.
This works fine
MyClass c1=new MyClass("A0001");
c1.myMethod(c1);
System.out.println(c1.Persons.get(0).Name); // output is: A0001_1
The classes are:
class MyClass{
public List<Person> Persons = new ArrayList<Person>();
public String name="";
MyClass(String name){
this.name=name;
}
void myMethod(MyClass c){
Persons.add(new Person(c));
}
}
class Person{
public static int Num=0;
public String Name="";
Person(MyClass c){
Num++;
this.Name=c.name+"_"+Num;
}
}
but I want it to be like this
MyClass c1=new MyClass("A0001");
c1.myMethod();
System.out.println(c1.Persons.get(0).Name);
class MyClass{
public List<Person> Persons = new ArrayList<Person>();
public String name="";
MyClass(String name){
this.name=name;
}
void myMethod(this){
// which Reference Variable calls this method?
System.out.println("name of the Reference Variable="+???);
Persons.add(new Person(this));
}
what can I put to ???
how programmatically can we show "c1" in ???
There is no reason to pass same object as parameter to its own method.
Also, there is no reason to make a method to accept another object of the same class as parameter to create Person object.
so if your Person object always creates by MyClass object and needs exact that MyClass object as constructor parameter, do this:
void myMethod(){
Persons.add(new Person(this));
}
I'm not sure to understand your need.
First, your question title makes me thing you want to use the injection/reflexion capabilities of Java.
Based on your code and explanations, I doubt you're looking for this complexity.
Second, this part is unclear. How the hell can we guess what you're trying to do here ?
void myMethod(){
MyClass c=??? // WHAT DO YOU WANT TO DO ?!!!!
Persons.add(new Person(c));
}
What you want is the constructor of Person1 class to decide of a Class to put the person in ?
If yes, something like this could do the trick (kindof a factory ?)
The MyClass keeps track of all create classes.
Besides, i guess that your class should be able to receive Person and Person1.
Code written oustide of IDE, some mistakes might been still here.
And once again, this is based on a partial understanding of your post.
class Person1 extends Person {
Person1() {
MyClass c= MyClass.getTheClass("My_Awesome_Class");
this.Name=c.name+"_"+Num;
c.addPerson1(this);
}
}
With:
class MyClass {
// keep track of created classes
private static HashMap<String,MyClass> classMap = new HashMap<String,MyClass>();
public List<Person> Persons = new ArrayList<Person>();
public String name="";
private MyClass(String name){
this.name=name;
}
void addNewPerson() {
Persons.add(new Person(c));
}
void addPerson1(Person1 p) {
}
// lazy factory
public static MyClass getTheClass(String classname) {
// class does not exist yet
if (! classList.containsKey(classname)) {
//create it
MyClass theNewClass = new MyClass(classname);
classList.put(classname, theNewClass);
}
return classMap.get(classname);
}
}
Your code becomes:
// MyClass constructor is no longer directly visible ...
MyClass c1 = MyClass.getTheClass("A0001");
c1.addNewPerson();
System.out.println(c1.Persons.get(0).Name);
Person1 my_pupil = new Person1(); // creates My_Awesome_Class if needed
MyClass c2 = MyClass.getTheClass("My_Awesome_Class");
System.out.println(c2.Persons.get(0).Name);
EDIT:
some answers pointed out that maybe you want the Person classes to have visibity on their Class. Someone answered that part : pass the Class as argument of Person constructor.
EDIT2:
well the question has changed since my post ...
In Java objects are mostly created on heap memory ,so we don't have name for objects in Java
You can get a hash Code by using this.hashCode();, this is not the address of your object in the heap , we don't get object's address in java
so you can get the name of the class from the object by using this.getClass().getName
Note: when we write MyClass c1=new MyClass("A0001"); , c1 is not the object of class MyClass its a Reference to the instance of class MyClass
To know more about it Check answer in the Following link

Java. Get/Set returns null

first post and first question.
I am a java beginner so I apologise in advance if my question is very basic, but I have tried for 2 days to find the answer on Internet and on StackOverFlow without success
What I am trying to do: I want to "set" the value of a variable, and then "get" it back multiple other times.
What is happening: the first time that I "get" it, it (correctly) returns the value that I initialized. the following times it returns "null"
Here the code
1) Main class
public class Provasetgetaltraclass {
public static void main(String[] args) {
set_e_get_1 set_e_get_1Obj = new set_e_get_1();
set_e_get_1Obj.execute_var_to_set_e_get1();
set_e_get_1Obj.execute_var_to_set_e_get2();
}
}
2) class with the actions
public class set_e_get_1 {
public void execute_var_to_set_e_get1(){
var_to_set_e_get var_to_set_e_getObj = new var_to_set_e_get();
var_to_set_e_getObj.setname("test");
System.out.println(var_to_set_e_getObj.getname());
}
public void execute_var_to_set_e_get2(){
var_to_set_e_get var_to_set_e_getObj = new var_to_set_e_get();
System.out.println(var_to_set_e_getObj.getname());
}
}
3) class with the variable and the set and get methods
public class var_to_set_e_get {
private String name;
public void setname (String new_name){
name = new_name;
}
public String getname (){
return name;
}
}
4) the result, when I run the main, is
test
null
(what I would like is test and test)
I don't want to store the variable in a database or a file unless necessary, as I'd like to have this working on the fly
If you can help me I'd really appreciate it
Many thanks
What happens is that in each call of the methods execute_var_to_set_e_get1 and execute_var_to_set_e_get2 you are creating different objects.
In the first one you are setting name to a String, but in the last, you are not doing that.
So, it will be null (by default).
Note: The behavior that you have described is of a static attribute. If you declase name as static, it will be shared between all the instances.
Your two methods execute_var_to_set_e_get1 and execute_var_to_set_e_get2 each create a different object of var_to_set_e_get class. You set the value of the property only in one of them, so of course it will be null in the other.
If you want the value you stored in the first object to be available in the second method, your first method has to return the object it creates, and the second method should accept that object :
public var_to_set_e_get execute_var_to_set_e_get1(){
var_to_set_e_get var_to_set_e_getObj = new var_to_set_e_get();
var_to_set_e_getObj.setname("test");
System.out.println(var_to_set_e_getObj.getname());
return var_to_set_e_getObj;
}
public void execute_var_to_set_e_get2(var_to_set_e_get var_to_set_e_getObj){
System.out.println(var_to_set_e_getObj.getname());
}
public static void main(String[] args) {
set_e_get_1 obj = new set_e_get_1();
var_to_set_e_get v = obj.execute_var_to_set_e_get1();
obj.execute_var_to_set_e_get2(v);
}

Categories

Resources