understanding how to copy data - java

I am working on some homework for entry level java, and i ran in to this. I have no idea what it is having me do. Is this literally just setting "Date" equal to the value in "Date d"? or am I missing something? I don't feel like that long of an explanation would be used for a one line piece of code.
Could someone please explain what is happening here and what I am missing?
Copy constructor: this is a constructor that accepts one parameter of
type Date and then sets the receiving (or executing) objects instance
variables equal to those of the parameter object. The result is that
the receiving object is a copy of the formal parameter object:
public Date( Date d )

All you need to do is take all the fields of d and copy them over to the new Date. So if a Date has a time, a day, a month, and a year, copy all those to the new Date. That's it.

class Complex {
private double re, im;
// A normal parametrized constructor
public Complex(double re, double im) {
this.re = re;
this.im = im;
}
// copy constructor
Complex(Complex c) {
System.out.println("Copy constructor called");
re = c.re;
im = c.im;
}
// Overriding the toString of Object class
#Override
public String toString() {
return "(" + re + " + " + im + "i)";
}
}
public class Main {
public static void main(String[] args) {
Complex c1 = new Complex(10, 15);
// Following involves a copy constructor call
Complex c2 = new Complex(c1);
// Note that following doesn't involve a copy constructor call as
// non-primitive variables are just references.
Complex c3 = c2;
System.out.println(c2); // toString() of c2 is called here
}
}

Related

why property overriding in kotlin makes primary constructor property zero

I'm trying to pass value to constructor and print the values.
open class Car(c: Int){
open var cost: Int = c
init {
println("This comes First $cost")
}
}
open class Vehicle(cc: Int) : Car(cc) {
override var cost: Int = 20000
init {
println("This comes Second $cost")
}
fun show(){
println("cost = $cost")
}
}
fun main() {
var vehicle = Vehicle(1000)
vehicle.show()
}
Output
This comes First 0
This comes Second 20000
cost = 20000
if i just comment this line
override var cost: Int = 20000
output would be
This comes First 1000
This comes Second 1000
cost = 1000
Why super constructor cost is zero when override the property in subclass?
I need this to be compared to java concept for better explanation here
In Java to create a mutable property cost, you need to define a field cost and a getter and setter:
public class Car {
private int cost;
public Car(int c) {
this.cost = c;
System.out.println("This comes First " + getCost());
}
public int getCost() { return cost; }
public void setCost(int cost) { this.cost = cost; }
}
Kotlin has the concept of a property embedded in the language, so you can achieve the same with only creating a var property as you did:
open class Car(c : Int){
open var cost : Int = c
init {
println("This comes First $cost")
}
}
This is much more concise from the developer perspective, but the implementation is the same. Kotlin compiler is generating a field cost, a get method and set method for us under the hood.
Now the interesting part. When you make the cost property in the parent class open and overrides it in the child class, you are actually overriding the get method. It is not possible to override a field, neither in Kotlin nor Java.
As #Pawel mentioned in his answer that's the java code for the Vehicle child class:
public class Vehicle extends Car {
private int cost = 20000;
#Override
public int getCost() {
return this.cost;
}
#Override
public void setCost(int var1) {
this.cost = var1;
}
public final void show() {
System.out.println("cost = " + getCost());
}
public Vehicle(int cc) {
super(cc);
System.out.println("This comes Second " + getCost());
}
}
When you execute println("This comes First $cost") in the parent class, you are actually executing System.out.println("This comes First " + getCost()); and the actual getCost() being called is the one in the child class Vehicle. As the child class cost field has not been initialized yet, as we are still executing the super(cc) call, its value is zero.
Have you looked at generated bytecode and tried to reverse decompile it back to java? If you're confused how Kotlin works under the hood often times it can help you understand.
In this case your classes in Java would look like this (i decompiled your code and cleaned it up a little):
public class Car {
private int cost;
public int getCost() {
return this.cost;
}
public void setCost(int var1) {
this.cost = var1;
}
public Car(int c) {
this.cost = c;
System.out.println("This comes First " + getCost());
}
}
public class Vehicle extends Car {
private int cost = 20000;
public int getCost() {
return this.cost;
}
public void setCost(int var1) {
this.cost = var1;
}
public final void show() {
System.out.println("cost = " + getCost());
}
public Vehicle(int cc) {
super(cc);
System.out.println("This comes Second " + getCost());
}
}
What's happening is open var is just declaration for setter and getter which Vehicle overrides.
Remember that initialization of super class always happen before child, so when Car constructor is executed Vehicle is still not initialized (Vehicle.cost is still 0).
That means in first case:
This comes First 0 // Car constructor prints 0 because it returns Vehicle.cost which is unitialized
This comes Second 20000 // Vehicle constructor returns initialized value
cost = 20000
And in second case where you DON'T override the cost, both Car and Vehicle return Car.cost:
This comes First 1000 // Car constructor assigns constructor parameter to Car.cost and returns it
This comes Second 1000 // Vehicle constructor returns Car.cost as well
cost = 1000
Also note that in first case your constructor parameter is meaningless: it gets assigned to Car.cost but that field is inaccessible because it's shadowed by Vehicle.cost.
This behavior may not be intuitive, but it's the result of how properties work with the JVM.
When you subclass Car, the Car initialization occurs before the subclass Vehicle initialization. So the println call in Car's init block accesses the property before Vehicle is initialized. Since this access amounts to calling a getter method in Java, it is accessing the subclass's getter, not its own since it's been overridden. Since the subclass has not initialized yet at this stage, its getter returns the default value of the backing field, 0.
If you do this with a non-primitive, non-nullable property, you can "trick" Kotlin into giving you a Java NullPointerException for what can normally be assumed to be non-null.
In either case, the default code inspections should warn you about trying to access an open property during initialization, because of this unexpected kind of behavior.
The work-around would be to use a private backing property:
open class Car(c : Int){
private var _cost: Int = c
open var cost : Int
get() = _cost
set(value) { _cost = value }
init {
println("This comes First $_cost")
}
}
In simple words.
when object is created Vehicle(1000)
- first init will get called
- then variables get initialized
step 1:- it will try to call constructor of Vehicle
step 2:- since it inherited Car it will try to call constructor of Car first
step 3:- it always look for override methods not overridden methods or properties So, $cost is pointing to override property.
step 4:- override var cost : Int = 20000 is not initialized when you are printing
println("This comes First $cost") as init run first then property will initialized.
step 5:- So $cost is by default zero.
Just try this, below open var cost : Int = c
put, var costTest : Int = c. "no open keyword"
Then, on Vehicle init put,
println("This comes Second $cost $costTest")
here you will get costTest = 1000.
Its because costTest you haven't override

Convert double to string and return it to main

A part of my homework is to convert three double variables to one String and print it from the main method. I have created a separate class where I try to create the string. When I try to print the string from the main method, i dont understand how to do it.
Main-class
public static void main(String[] args) {
System.out.println(Point.toString());
}
Point
public class Point {
public String toString(Double xVal, Double yVal, Double zVal){
String p= Double.toString(this.xVal) + ":" + Double.toString(this.yVal) +
":" + Double.toString(this.zVal);
return p;
}
}
This is just a part of my code, can someone help me with the part where i try to print the string?
It seems that you tried to create some sort of utility class, so...
First you need to make the method which prints the values in Point class static, so you don't need to create instances of Point in order to call it.
Second, I highly recommend to change the method name in class Point because there is a toString method already inherited from Object. This may lead to confusions since the goal of the inherited method is not the same the one you created this toString method for.
Also, be careful inside the method to use the values received as parameter and not the (missing) instance attributes. That is, use values xVal, yVal and zVal, not this.xVal, this.yVal and this.zVal.
So, this would go kind of this way:
public class Point {
// changed from `toString` to `convertToString`, use the name which fits better your needs, except `toString`
public static String convertToString(Double xVal, Double yVal, Double zVal) {
// use `xVal`, not `this.xVal` and the same for the other variables
String p = Double.toString(xVal) + ":" + Double.toString(yVal) + ":" + Double.toString(zVal);
return p;
}
}
Then in your main class:
public class Main {
public static void main(String[] args) {
System.out.println(Point.convertToString(1d, 2d, 3d)); // you can replace this sample values with the real ones
}
}
Of course, there are many ways to do this, but the "proper" way, using toString would be to make the x, y and z values attributes of the class (and, optionally, a constructor and getters and setters for those attributes), and have toString print the values of those attributes of the current instance.
public class Point {
Double xVal, yVal, zVal;
public Point(Double x, Double y, Double z) {
this.xVal = x;
this.yVal = y;
this.zVal = z;
}
public String toString() {
return String.format("%s:%s:%s", this.xVal, this.yVal, this.zVal);
}
}
Here, String.format("%s:%s:%s", ...) is a nicer way to format the string with the three numbers, but you can just as well keep yours. The nth %s will automatically convert the parameter in that position to string and insert it at that position. You could also use e.g. %.2f for specific floating -point format with more options.
You can create a new instance of the Point class with the given coordinates and print it. Here, you do not have to explicitly call toString, as it will be automatically called when println tries to convert its argument to a string.
public static void main(String[] args) {
Point p = new Point(1.1, 2.2, 3.3);
System.out.println(p);
}
You need to create object of the class Point then invoke the method toString with the three double value as arguments, like you defined inside Point class.
public static void main(String[] args) {
Point p = new Point();
System.out.println(p.toString(2.0,3.5,4.6));
}
I think the correct way is to create a new point with its parameters and override the toString method inherited:
public class Point{
Double xVal; Double yVal; Double zVal;
void Point(Double xVal, Double yVal, Double zVal)
{
this.xVal = xVal;
this.yVal = yVal;
this.zVal = zVal;
}
#Override
public String toString(){
String p= Double.toString(this.xVal) + ":" + Double.toString(this.yVal) +
":" + Double.toString(this.zVal);
return p;
}
}
So the main:
public static void main(String[] args) {
Point p = new Point(1.3,2.0,.30);
System.out.println(p.toString());
}

Error in Creating Java array with Multiple Data Types

Can someone please explain why it doesn't work? The error is at obj[0][0]=1;. It says that GPA can't be converted to int, same thing for String variable assignment s.
public class GPA {
public String s;
public int n;
public GPA[][] a;
//constructor
public GPA(GPA[][] a){}
public static void main(String[] args) {
GPA[][] obj=new GPA[2][2];
obj[0][0]=1; //error here
}
}
obj is an Array of GPA objects.
obj[0] = 1 means you are assigning the first element of that array to an intvalue. It should be an object of type GPA.
You can do it like
obj[0] = new GPA("John Doe", 6);
I would also recommend using Java convention, by making variables private and set() them by public methods like setter()s.
The question is changed which makes the answer irrelevant.
It won't work and gives you compile time error because GPA is class type and you are trying to assigning int value to it.
You have two options.
Option 1:
GPA[] obj = new GPA[4];
obj[0] = new GPA();
obj[0].n = 1;
Option 2:
You can make members of GPA private and use setters to set the value. Below is example.
public class GPA {
private String s;
private int n;
private GPA[] a;
public GPA() {}
public GPA(GPA[] a) {}
public String getS() {
return s;
}
public void setS(String s) {
this.s = s;
}
public int getN() {
return n;
}
public void setN(int n) {
this.n = n;
}
public GPA[] getA() {
return a;
}
public void setA(GPA[] a) {
this.a = a;
}
}
and then set using setter.
obj[0].setN(1);
It's not good programming practice to make your members public. It is always advised to use setters.
What you're actualy doing is trying to assign int and/or string to variable that is expecting object of GPA class.
Didn't you want to do
obj[0].n=1;
obj[0].s="text;"
For array of object you always have to create on object at that position first. otherwise you alway get a NullPointerException.
So what you need goes something like this
GPA[][] obj = new GPA[2][2];
obj[0][0] = new GPA();
obj[0][0].s="text";
obj[0][0].n=1;
...
and so on for every position there is.
Java Arrays are homogeneous(Javascript arrays are heterogeneous). That means you can only store the type of elements which you used while creating an Array.
ex: `int intArray[];` //We can store only int type elements(it also accepts Integer etc.. types but java converts to int then store it)
Now, apply the same rule to public GPA[] a; here a is an array of type GPA. So it accept only GPA type object.
That mean, you can store values like as below
a[0] = new GPA("nameHere", 6);
If I want to store either a string or an int, one at a time( I have
to make table of Student Name vs GPA) ,how do I do it?
One solution to this requirement is, assign a variable using constructor or setter method.
GPA[] obj = new GPA[2];
obj[0] = new GPA("first", 6); // here you need to create a new constructor
or
obj[1] = new GPA(); // Here default constructor will work and you need to have setter methods
obj[1].setName("second");
Hope this help...

Java print string and int on same line

I was trying to print a string and int on a same line. But I get an error. I know my way around this error but why does the line System.out.println("This is a string: %i", c2.a);gives error whereas the line System.out.println("This is class method" + c2.a ); gives the correct output. Below is my code.
public class MyClass
{
private int a;
public double b;
public MyClass(int first, double second)
{
this.a = first;
this.b = second;
}
// new method
public static void incrementBoth(MyClass c1) {
c1.a = c1.a + 1;
c1.b = c1.b + 1.0;
}
//pass by valuye therefore no change
public static void incrementA(int a)
{
a = a+1;
}
public static void main(String[] args)
{
MyClass c1 = new MyClass(10, 20.5);
MyClass c2 = new MyClass(10, 31.5);
// different code below
incrementBoth(c2);
incrementA(c1.a);
System.out.println("This is a object passing: %i",c2.a);
System.out.println("This is object passing: " + c2.a );
System.out.println("This is pass by value: %d",c1.a);
}
}
My other question is does the line incrementBoth(c2) changes value of c2 because here whole object is passed to the method rather than passing by value in incrementA(c1.a)
You need to use the printf method and not println.
println is used to print primitive types, Strings and objects as they are. Also, println takes only one argument as input. That is the reason you are getting an error when you pass multiple arguments to it in your code.
printf on the other hand is used to format and then print the formatted string to the Standard output / error. This is what you should use in your code above for formatting the output.
Here's a reference to the tutorials.
Hope this helps!
Try:
int x = 3;
System.out.println("This is my number" + x);
The output should be:
This is my number 3

when calling method from another class - retuns an incomprehensible value JAVA

When i run 2nd class i see " Car#15ab7626 " why ? in teory i must see 20, yes?
I have alredy used differnet combinatoin & ask google but dont understent why.
i have 1 class
public class Car {
public int drive(int a) {
int distance = 2*a;
return distance;
}
}
and 2nd class
public class CarOwner {
public static void main(String[] args) {
Car a = new Car();
a.drive(10);
System.out.println(a);
}
}
You are printing the car object, not the result printed by drive
That incomprehensible value JAVA is textual representation of Object.
When you do System.out.println(a); then by default toString() method calls on passed object.
As per docs of toString()
Returns a string representation of the object. In general, the toString method returns a string that "textually represents" this object.
So
Car#15ab7626 is the textual representation of Values class.
To print result which is returned by your drive() method, print,
System.out.println(a.drive(10));
If you want to print the result from the drive() method, assign the result to a variable and then print it.
int result = a.drive(10);
System.out.println("Result = " + result);
or directly pass the result to the System.out.println() method;
System.out.println("Result = " + a.drive(10));
If you want to print the a object in a readable way, override the toString() method in the Car class definition.
#Override
public String toString() {
return "This is a car"; //for example
}
You are returning the value you have from a drive method, but you're not printing it.
To print out the value of the drive method, use
public class CarOwner {
public static void main(String[] args) {
Car a = new Car();
System.out.println(a.drive(10));
}
}
That's not the way method return values work. If you want to see the result as 20, replace your SOP with the following
System.out.println(a.drive(10));

Categories