So in my Registration class I have:
public class Registration {
private Student student;
private Course course;
private String semester;
public Registration(Student st, Course co, String sem)
{
student = st;
course = co;
semester = sem;
}
}
I'm stuck on how do I call the full initialized constructor (containing the Student object, the Course object, and the string containing the semester) to an object in another class.
(btw all the classes are in the same package)
It might look something like :
Registration myRegistrationVariable = new Registration(new Student(), new Course(), "spring semester");
or you could create these values ahead of time then supply them to the constructor like this:
//initialize student with whatever fields you have for it.
Student student = new Student();
//initialize Course with whatever fields you have for it.
Course course = new Course();
//create a string
String s = "Fall Semester";
Registration r = new Registration(student, course, s);
Keep in mind the constructor of any given class is called when you use the new keyword.
So new Registration as used above will call your constructor with 3 arguments, (because we gave it 3 arguments). Calling the constructor with no args, by using new Registration() will call your no arg constructor. If the number or types of arguments don't match one of your constructors, an exception will be thrown.
Related
I've got the following code as an example(I've removed most of the code to make it easier)
Main class:
class TestStudent_3
{
// To update student name to other name
private void updateObject (Student s, String otherName)
{
s.setName (otherName);
}
public static void main (String [] args)
{
... All variables, methods and scanner inputs etc removed ...
Student s = new Student (name, gender, age, subject1, subject2);
s.displayStudentInfo ();
// If you wish to change one the fields, you need to use mutator methods
TestStudent_3 ts = new TestStudent_3 ();
ts.updateObject (s, "New Name");
s.displayStudentInfo ();
}
}
Student class:
class Student
{
private String name;
... All variables, methods and scanner inputs etc removed ...
public void setName (String name)
{
this.name = name;
}
}
My question is what's these few lines in the main method doing? And why can it update the existing record('s')
TestStudent_3 ts = new TestStudent_3 ();
What's this doing? Creating a new object ts?
ts.updateObject (s, "New Name");
Passing Student s object variables(contents) over to the updateObject method together with "New Name" string, why does this work?
Thanks in advance!
Break it down.
s.setName(otherName);
sets the Name in instance s to otherName
ts.updateObject (s, "New Name");
is acting like a proxy of sorts. It accepts an instance of s and the name and then
does the same thing in the updateObject method.
It seems you are confused why the ts object had to be created with TestStudent_3 ts = new TestStudent_3 (); in order to update the Student s.
updateObject is not static, and is part of the TestStudent_3 class, so in order to call that method, you need to have an object of the class and invoke it using the object, as you see with the ts.updateObject(s, "New Name") where ts is the object created just so you can use the method.
Realistically updateObject should be static the way it is written:
private static void updateObject (Student s, String otherName)
Because the ts object is not used at all for logic of the method, it is completely unnecessary. If it was static, then you would just be able to use updateObject(s, "New Name") instead without the ts. (although you might as well just call s.setName("New Name") directly).
You pass an object reference to object s into the updateObject method.
So the updateObject method call:
<reference to s>.setName(otherName)
or you can say:
s.setName(otherName)
That will change the name value of the Student s object.
In the next line in the main method you call:
s.displayStudentInfo();
Thats kind of equal to:
<reference to s>.displayStudentInfo();
I wish to know which are case where java reference casting is helpful?
I tried with a parent and child class and verified that we don't need any casting when parent class object is assigned object of child class.
But reverse it not working like assigning object of parent class to object of child class, it give compile time error like "error: incompatible types: Person cannot be converted to Student Student student2 = person1;"
Once I do explicit casting the compiling works but it fail at run time with exception "java.lang.ClassCastException: Person cannot be cast to Student". I could not understand if casting is not going to work at run time what is benefit of providing this feature or is there any case where it is working and helpful.
class Person {
private String name;
Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
class Student extends Person {
private int rollNo;
Student(String name, int rollNo) {
super(name);
this.rollNo = rollNo;
}
public int getRollNo() {
return rollNo;
}
}
class Hello {
public static void main(String[] args) {
Person person1 = new Person("person1");
Student student1 = new Student("student1", 11);
tudent student2 = (Student) person1;
}
}
There are two things to think about when looking at an object:
the object’s compile-time type, i.e. its declared type;
the object’s runtime type, i.e. what type it actually is when your program is running.
These are the rules:
An object declared as a child class can be assigned to a reference of a parent class; no explicit cast needed.
An object declared as a parent class can be explicitly cast to a child class only if the object is actually a child-class object at runtime.
Example:
private static void displayPerson(Person person) {
System.out.println(person.name);
}
private static void displayStudent(Student student) {
System.out.println(student.name + ": " + student.grade);
}
public static void main(String[] args) {
Student student = new Student();
displayPerson(student); // rule 1
Person student2 = new Student(); // declared type is Person, runtime type is Student
displayStudent(student2); // ERROR - won't compile
displayStudent((Student) student2); // rule 2 - cast is required
}
You can cast to a 'more abstract type' whenever you want. For instance Student into Person.
Everywhere in your source code, it will be better to work with most abstract types. The main reason is that it will allow to change implementation without having to change the calling source code, or the methods' signature.
For instance, think about changing implementation use from a HashMap to a LinkedHashMap without having to change anything else because you are working only with Map generic type.
Even if lower cast is allowed (the one you tried: Person into Student), it is generally not recommended and generally means there is an issue in your classes design.
To conclude, because it is a runtime operation, you will learn it is not possible during execution instead of compilation time.
I have the following class:
public class MotherFactory {
private String food = "banana";
private static FoodFactory<Banana> foodFactory = new BananaFactory();
public MotherFactory() {
}
}
In this class i declare a FoodFactory for BananaHsm, which i hardcoded in (The food string has no use in this yet). What i want however, is that the declaration of the FoodFactory changes according to the food String. E.g.: For private String food = "apple", <BananaFactory> changes to <AppleFactory>, and new BananaFactory() to new AppleFactory and so on. i already thought of using a switch or if/else, however these would be declared inside the constructor, which doesnt make the variables usable for the whole instance.
Are there any ways to do this?
I am trying to build a class with a constructor, mutators and accessors. Reading through books and online, I am made to learn that you can call a constructor with or without parameters. However, my case below seems not to work. I am not even able to compile without errors. It works when I use student jane = new student(""). What am I doing wrong?
Devolution.java:6: cannot find symbol
symbol : constructor student()
location: class Governor
student jane = new student();
^
public class designers {
public static void main(String[] args) {
student jane = new student();
student smith = new student("jane", "36365355", "Nairobi", "Male");
System.out.println("Janes's Properties: "+jane.name() + " " + jane.nationalID() + " " + jane.county()+" "+jane.gender());
System.out.println("Smith's Properties: "+smith.name() + " " + smith.nationalID() + " " + smith.county()+" "+smith.gender());
}
}
other code is below
public class student {
//Private fields
private String name;
private String nationalID;
private String county;
private String gender;
//Constructor method
public student(String name, String nationalID, String county, String gender)
{
this.name = name;
this.nationalID = nationalID;
this.county = county;
this.gender = gender;
}
//Accessor for name
public String name()
{
return name;
}
//Accessor for nationalID
public String nationalID()
{
return nationalID;
}
//Accessor for county
public String county()
{
return county;
}
//Accessor for gender
public String gender()
{
return gender;
}
}
A constructor is a way of creating an instance of a class:
Student s = new Student(...);
will create a new instance of the Student class and enable you to access it using s.
Often, when you create an instance of a class, you need to specify certain information that's used in building the instance. In the case of a student, that might be the name, the age, and so on. You'd have a constructor that looks like this:
public Student(String name, int age) {
//...
}
But in some contexts, you can build an instance of a class without needing (at least initially) to specify anything. So you might, for instance, have a constructor like this
public Student() {
//...
}
which leaves the name and age fields blank or zeroed out, until you later set them with another method of the class.
The critical point for what you're doing is that you've made a constructor that requires various parameters, but you haven't specified one like this second example that doesn't require any. As things stand, you can write
Student s = new Student("Bob", "ABC12345", "Surrey", "Male");
because you've got a constructor that takes four Strings as arguments. But you can't write
Student s = new Student();
because you didn't create a constructor that takes no arguments.
The slight wrinkle in this is that if you don't specify any constructors in your class, then Java will automatically create one for you that takes no arguments and doesn't do anything special. So if you don't write any constructors, you'll get one for free that looks like this:
public Student() {
}
But that's only if you don't write any of your own. Since you've specified one that does take parameters, Java won't give you a no-argument one for free. You have to put it in yourself if you want to be able to create instances without any arguments.
You've only written one constructor - the one with four parameters. You don't have a constructor without parameters, so you can't write new student().
Note that if you don't write any constructors at all, the compiler will automatically make a constructor for you, without parameters, but as soon as you write one constructor, this doesn't happen.
By the way, most people use capital letters for class names (so Student, not student). This makes it easy to distinguish them from the names of other identifiers. It would be good for you to get into the habit of doing the same.
You don't have a constuctor without parameters in the student class. Such a constructor is generated by the compiler only if you haven't defined any other constructors, which you have.
Just add the constructor :
public student()
{
this.name = null;
this.nationalID = null;
this.county = null;
this.gender = null;
}
You need to make another constructor as follow:
public Student(){
//do things here
}
Explanation:
When no constructors are defined in a class then there is a default constructor(without
any parameters) already. In which case you don't need to define it. But if you have any constructor with some parameters, then you need to define the constructor without parameters as well.
Its called overloading the constructor. In your class, declare a constructor again without parameter requirements. See this post for more info
You don't have a constructor without parameters. That would only be the case when you had not write an own one. When you want to have the possibility to make an object of the class with or without parameters, you need two different constructors in your code.
Is there a way to create a new class from a String variable in Java?
String className = "Class1";
//pseudocode follows
Object xyz = new className(param1, param2);
Also, if possible does the resulting object have to be of type Object?
There may be a better way, but I want to be able to retrieve values from an XML file, then instantiate the classes named after those strings. Each of these classes implement the same interface and are derived from the same parent class, so I would then be able to call a particular method in that class.
This is what you want to do:
String className = "Class1";
Object xyz = Class.forName(className).newInstance();
Note that the newInstance method does not allow a parametrized constructor to be used. (See Class.newInstance documentation)
If you do need to use a parametrized constructor, this is what you need to do:
import java.lang.reflect.*;
Param1Type param1;
Param2Type param2;
String className = "Class1";
Class cl = Class.forName(className);
Constructor con = cl.getConstructor(Param1Type.class, Param2Type.class);
Object xyz = con.newInstance(param1, param2);
See Constructor.newInstance documentation
Yes, you can load a class on your classpath given the String name using reflection, using Class.forName(name), grabbing the constructor and invoking it. I'll do you an example.
Consider I have a class:
com.crossedstreams.thingy.Foo
Which has a constructor with signature:
Foo(String a, String b);
I would instantiate the class based on these two facts as follows:
// Load the Class. Must use fully qualified name here!
Class clazz = Class.forName("com.crossedstreams.thingy.Foo");
// I need an array as follows to describe the signature
Class[] parameters = new Class[] {String.class, String.class};
// Now I can get a reference to the right constructor
Constructor constructor = clazz.getConstructor(parameters);
// And I can use that Constructor to instantiate the class
Object o = constructor.newInstance(new Object[] {"one", "two"});
// To prove it's really there...
System.out.println(o);
Output:
com.crossedstreams.thingy.Foo#20cf2c80
There's plenty of resources out there which go into more detail about this, and you should be aware that you're introducing a dependency that the compiler can't check for you - if you misspell the class name or anything, it will fail at runtime.
Also, there's quite a few different types of Exception that might be throws during this process. It's a very powerful technique though.
This should work:
import java.lang.reflect.*;
FirstArgType arg1;
SecondArgType arg2;
Class cl = Class.forName("TheClassName");
Constructor con = cl.getConstructor(FirstArgType.class, SecondArgType.class);
Object obj = con.newInstance(arg1, arg2);
From there you can cast to a known type.
This worked a little more cleanly for me in JDK7, while the answers above made things a bit more difficult than they needed to be from a newbie perspective: (assumes you've declared 'className' as a String variable passed as a method parameter or earlier in the method using this code):
Class<?> panel = Class.forName( className );
JPanel newScreen = (JPanel) panel.newInstance();
From this point you can use properties / methods from your dynamically-named class exactly as you would expect to be able to use them:
JFrame frame = new JFrame(); // <<< Just so no-one gets lost here
frame.getContentPane().removeAll();
frame.getContentPane().add( newScreen );
frame.validate();
frame.repaint();
The examples in other answers above resulted in errors when I tried to .add() the new 'Object' type object to the frame. The technique shown here gave me a usable object with just those 2 lines of code above.
Not exactly certain why that was - I'm a Java newbie myself.
Another one:
import java.lang.reflect.Constructor;
public class Test {
public Test(String name) {
this.name = name;
}
public String getName() {
return name;
}
public String toString() {
return this.name;
}
private String name;
public static void main(String[] args) throws Exception {
String className = "Test";
Class clazz = Class.forName(className);
Constructor tc = clazz.getConstructor(String.class);
Object t = tc.newInstance("John");
System.out.println(t);
}
}
A Sample Program to Get Instance of a class using String Object.
public class GetStudentObjectFromString
{
public static void main (String[] args) throws java.lang.Exception
{
String className = "Student"; //Passed the Class Name in String Object.
//A Object of Student will made by Invoking its Default Constructor.
Object o = Class.forName(className).newInstance();
if(o instanceof Student) // Verify Your Instance that Is it Student Type or not?
System.out.println("Hurrey You Got The Instance of " + className);
}
}
class Student{
public Student(){
System.out.println("Constructor Invoked");
}
}
Output :-
Constructor Invoked
Hurrey You Got The Instance of Student