I have a class model called "Car".
If I want to create a new object of "Car" I can do something like this:
Car car = new Car();
But now, I made this class implements Parcelable. What is the best way of creating a new object of the class "Car"?
Right now I am doing this way:
Car car = new Car("blue");
And I am adding a new constructor to my model Class:
public class Car implements Parcelable {
public String color;
#Override
public int describeContents() { return 0; }
#Override
public void writeToParcel(Parcel dest, int flags) { dest.writeString(color); }
public static final Creator<Car> CREATOR = new Creator<Car>() {
public Car createFromParcel(Parcel in) { return new Car(in); }
public Car[] newArray(int size) { return new Car[size]; }
};
private Car(Parcel in) { color = in.readString(); }
public Car(String myColor) { color = myColor; }
}
Since I am new to this class Parcelable I'm not sure if this is the best aproach. Is anything bad having two constructors in my class? Is there any other more efficient way to do this?
I am afraid that adding this second constructor my application should lose some performance in creating new objects of this class.
Since I am new to this class Parcelable I'm not sure if this is the best aproach. Is anything bad having two constructors in my class? Is there any other more efficient way to do this?
It depends what you need, but your implementation of parcelable patters seems to be okey.
If u need to pass efficiently your object throught intent or arguments bundle, it is best approach. Parcelable is android more efficient implementation of class serialization.
If you want little less optimal (but easier) you could use serializable, this is default java approch, it's a bit slower, and has its own drawbacks ^^.
And if more important for you is readability of generated state (parcelable and serializable will make a byte stream from your object), you might want to use Json convertion (and for that i would suggest gson.
I am afraid that adding this second constructor my application should lose some performance in creating new objects of this class.
There is nothing wrong with multiple constructors. They are simply, a way to initialize your object state. Nothing more nothing less.
PS: For your old method of creating a car to work:
Car car = new Car();
Simply add empty constructor:
public Car() { }
Cheers.
Related
I have created a (generic) class Store, which I use to get 3 stores(smithy, jeweler and bookstore). The store is basically just an ArrayList, which holds different objects, that can be bought in each store. Now I want to limit the smithy to only hold weapons, the jeweler to only hold rings, etc.
I tried realizing that like this:
Store<Weapon> smithy = new Store<>();
Store<Ring> jeweler = new Store<>();
Store<Scroll> bookstore = new Store<>();
However do I get an error later on in the code, because the method only accepts the type(Object, Store<Object>) and not (Object,Store<Weapon>). But the Weapon class is a subclass of my Object class, so I don't understand why this is a problem.
My Store class:
public class Store <T extends Object>{
/...
}
My Object Class:
public class Object {
//Konstruktor
public Object() {
}
}
My Weapon class :
public class Weapon extends Object {
//Konstruktor
public Weapon () {
super();
};
The piece of code I get the problem in:
this.myPlayer.buy(this.smithy.getItemAt(itemNr), this.smithy);
The buy method:
public void buy(Object obj, Store<Object> store){
//...}
the error:
the method buy(Object,Store<Object>) in the type Player is not applicable for the arguments (Object, Store<Weapon>)
Since I have three different stores with each their own kind of Objects(Weapon, Ring, Scroll) I cannot just change the buy method to (Object, Store<Weapon>). And writing three methods for each store seems a bit much to me.
I appreciate your helping.
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.
I have different weapon classes with various attributes and functions (some of which are similar). I am trying to iterate through objects of classes and trying to access those attributes based on certain conditions. Below are some of the objects I created and am storing inside an ArrayList of type Object.
Ak117 ak117 = new Ak117();
Ak47 ak47 = new Ak47();
Bk57 bk57 = new Bk57();
ArrayList <Object> weaponObjects = new ArrayList<>(Arrays.asList(ak117, ak47, bk57);
int damage = weaponObjects.get(0).damageStats;
//damage stats is an integer inside AK117 class that returns its damage
When I do this Eclipse can't identify .damageStats; and throws an error.
Is there any way wherein I can access all attributes or methods of these objects?
You can use Interface or Abtract class
Example
Create an interface that contains all the common methods of the classes:
public interface Weapon{
int getDamageStats();
void shoot();
// more method
}
Creat class implements this interface
class Ak47 implements Weapon{
#Override
public int getDamageStats() {
return 100;
}
#Override
public void shoot() {
System.out.println("Ak shoot");
}
}
class Bk47 implements Weapon{
#Override
public int getDamageStats() {
return 500;
}
#Override
public void shoot() {
System.out.println("Bk shoot");
}
}
Call List by Weapon:
Ak47 = new Ak47();
Bk47 = new Bk47();
ArrayList <Weapon> weaponsList = Arrays.asList(ak47, bk47);
int damage = weaponsList .get(0).getDamageStats();
you need something like the below:
ArrayList <Weapon> weaponsList = Arrays.asList(ak117, ak47, bk47);
If you only store the Objects you can only call the Object's methods for each array list entry. If you use Weapon (an interface for all weapons that defines getDamageStats()) all subclasses can then have this method called.
You need to write a getter in every weapon class.
public class Ak47 {
int damageStats;
public int getDamageStats() {
return damageStats;
}
}
You can access damageStats in another class by creating an instance of Ak47 and calling the getDamgeStats on it.
public class Example {
Ak47 ak47 = new Ak47();
int example = ak47.getDamageStats();
}
I think you should rethink adding inheritance, I am not a gun expert but maybe by country idk. Another option is with abstract class and just throw the methods that are common and modify the others. Then just like Rob Evans said iterate over a list, but my advise is to use new ArrayList<>(new Ak47(), ...etc) and not Arrays.asList.
Yep, this is a casual problem with the Object class. If you initiate your ArrayList as an Object, as someone already said, you'll only be able to reach Object Class's methods. By what you sent, we can think that your other classes share communs attributes. So the best idea would be to pass by a SuperClass, which will be extended by every others classes and have a getter on it (in this case, a getDamageStats()). Then you initiate your ArrayList as the SuperClass instead of Object and you'll be able to reach what you seem to want
I have a bit of code that requires a copy of an object be sent in. This requirement is because a service (runtime library) that is called modifies the object sent. This object also needs to expose setters, in case the doThing method below needs to set any field in the ImportantObj class. This implementation is pending change, but does not have a reasonable expectation to be changed in the near future. My workaround is to provide a class that does as follows:
public class DangerousCallWrapper<T> implements DangerousCaller<T> {
public T doThing(T dataObject) {
T cloneOfDataObject = #Clone of dataObject
// This service modifies the cloneOfDataObject... dangerous!
Optional<T> result = service.doThing(cloneOfDataObject);
return result.orElseThrow(() -> new RuntimeException("No data object returned");
}
}
public interface DangerousCaller<T> {
/**
* Performs the functionality of the DangerousService
*/
public T doThing(T);
}
public DangerousService<T> {
public T doThing(T data) {
data.importantField = null;
data.thing = "Done!";
return data;
}
}
public static void main() {
DangerousService service = new DangerousService<ImportantObj>();
ImportantObj important = new ImportantObj().setImportantField("Password for my bank account").setThing("Undone");
service.doThing(important);
//would fail this check
assertNotNull(important.importantField);
DangerousCallWrapper wrapper = new DangerousCallWrapper<ImportantObj>();
ImportantObj important = new ImportantObj().setImportantField("Password for my bank account").setThing("Undone");
service.doThing(important);
//would not fail this check
assertNotNull(important.importantField);
}
So the first line of that method is where I am stuck. It is a generic type, so I can't explicitly call some cloning utility like Jackson, or similar.
So I thought I would just add T extends Cloneable to the method... but I opened the can of worms that Cloneable is beyond taboo (https://www.artima.com/intv/bloch13.html). I have also read that copy constructors are probably the best way to handle this... However, I am unsure of how to denote that using the generics.
So my thought was to provide an interface Copyable that does what you would expect Cloneable to do: expose a method, copy() that will create a new instance of the class.
Does this constitute a viable approach?
To solve your problem you need to polymorphically make a copy of dataObject like this:
T cloneOfDataObject = dataObject.clone();
and the issue is that Cloneable does not have a clone() method, so the above does not compile.
Given this premise, it does make sense to create your own Copyable interface that defines a clone() method so you can leverage already-implemented clone() methods (if they exist) on the classes of your data object. For maximum effectiveness this interface would need to be generic as well:
interface Copyable<T> {
public T clone();
}
and the type bound:
public class DangerousCallWrapper<T extends Copyable<T>>
implements DangerousCaller<T> {
I have the following classes
class Person {
private String name;
void getName(){...}}
class Student extends Person{
String class;
void getClass(){...}
}
class Teacher extends Person{
String experience;
void getExperience(){...}
}
This is just a simplified version of my actual schema. Initially I don't know the type of person that needs to be created, so the function that handles the creation of these objects takes the general Person object as a parameter.
void calculate(Person p){...}
Now I want to access the methods of the child classes using this parent class object. I also need to access parent class methods from time to time so I CANNOT MAKE IT ABSTRACT.
I guess I simplified too much in the above example, so here goes , this is the actual structure.
class Question {
// private attributes
:
private QuestionOption option;
// getters and setters for private attributes
:
public QuestionOption getOption(){...}
}
class QuestionOption{
....
}
class ChoiceQuestionOption extends QuestionOption{
private boolean allowMultiple;
public boolean getMultiple(){...}
}
class Survey{
void renderSurvey(Question q) {
/*
Depending on the type of question (choice, dropdwn or other, I have to render
the question on the UI. The class that calls this doesnt have compile time
knowledge of the type of question that is going to be rendered. Each question
type has its own rendering function. If this is for choice , I need to access
its functions using q.
*/
if(q.getOption().getMultiple())
{...}
}
}
The if statement says "cannot find getMultiple for QuestionOption." OuestionOption has many more child classes that have different types of methods that are not common among the children (getMultiple is not common among the children)
NOTE: Though this is possible, it is not at all recommended as it kind of destroys the reason for inheritance. The best way would be to restructure your application design so that there are NO parent to child dependencies. A parent should not ever need to know its children or their capabilities.
However.. you should be able to do it like:
void calculate(Person p) {
((Student)p).method();
}
a safe way would be:
void calculate(Person p) {
if(p instanceof Student) ((Student)p).method();
}
A parent class should not have knowledge of child classes. You can implement a method calculate() and override it in every subclass:
class Person {
String name;
void getName(){...}
void calculate();
}
and then
class Student extends Person{
String class;
void getClass(){...}
#Override
void calculate() {
// do something with a Student
}
}
and
class Teacher extends Person{
String experience;
void getExperience(){...}
#Override
void calculate() {
// do something with a Teacher
}
}
By the way. Your statement about abstract classes is confusing. You can call methods defined in an abstract class, but of course only of instances of subclasses.
In your example you can make Person abstract and the use getName() on instanced of Student and Teacher.
Many of the answers here are suggesting implementing variant types using "Classical Object-Oriented Decomposition". That is, anything which might be needed on one of the variants has to be declared at the base of the hierarchy. I submit that this is a type-safe, but often very bad, approach. You either end up exposing all internal properties of all the different variants (most of which are "invalid" for each particular variant) or you end up cluttering the API of the hierarchy with tons of procedural methods (which means you have to recompile every time a new procedure is dreamed up).
I hesitate to do this, but here is a shameless plug for a blog post I wrote that outlines about 8 ways to do variant types in Java. They all suck, because Java sucks at variant types. So far the only JVM language that gets it right is Scala.
http://jazzjuice.blogspot.com/2010/10/6-things-i-hate-about-java-or-scala-is.html
The Scala creators actually wrote a paper about three of the eight ways. If I can track it down, I'll update this answer with a link.
UPDATE: found it here.
Why don't you just write an empty method in Person and override it in the children classes? And call it, when it needs to be:
void caluculate(Person p){
p.dotheCalculate();
}
This would mean you have to have the same method in both children classes, but i don't see why this would be a problem at all.
I had the same situation and I found a way around with a bit of engineering as follows - -
You have to have your method in parent class without any parameter and use - -
Class<? extends Person> cl = this.getClass(); // inside parent class
Now, with 'cl' you can access all child class fields with their name and initialized values by using - -
cl.getDeclaredFields(); cl.getField("myfield"); // and many more
In this situation your 'this' pointer will reference your child class object if you are calling parent method through your child class object.
Another thing you might need to use is Object obj = cl.newInstance();
Let me know if still you got stucked somewhere.
class Car extends Vehicle {
protected int numberOfSeats = 1;
public int getNumberOfSeats() {
return this.numberOfSeats;
}
public void printNumberOfSeats() {
// return this.numberOfSeats;
System.out.println(numberOfSeats);
}
}
//Parent class
class Vehicle {
protected String licensePlate = null;
public void setLicensePlate(String license) {
this.licensePlate = license;
System.out.println(licensePlate);
}
public static void main(String []args) {
Vehicle c = new Vehicle();
c.setLicensePlate("LASKF12341");
//Used downcasting to call the child method from the parent class.
//Downcasting = It’s the casting from a superclass to a subclass.
Vehicle d = new Car();
((Car) d).printNumberOfSeats();
}
}
One possible solution can be
class Survey{
void renderSurvey(Question q) {
/*
Depending on the type of question (choice, dropdwn or other, I have to render
the question on the UI. The class that calls this doesnt have compile time
knowledge of the type of question that is going to be rendered. Each question
type has its own rendering function. If this is for choice , I need to access
its functions using q.
*/
if(q.getOption() instanceof ChoiceQuestionOption)
{
ChoiceQuestionOption choiceQuestion = (ChoiceQuestionOption)q.getOption();
boolean result = choiceQuestion.getMultiple();
//do something with result......
}
}
}