I'm learning about constructors, but the videos that I've watched don't seem to help and everything I find on google seems to describe it in an advanced way.
I want to write a simple program which takes two inputs, a name (String) and an id (integer) and then just outputs it as "id" - "name". So for example:
01 - hello
This is the program that I'm trying to fix:
import java.util.Scanner;
public class ConstructorTest {
public static void main(String[] args) {
ConstructorTest();
toString(null);
}
//Constructor
public ConstructorTest(){
Scanner name = new Scanner(System.in);
Scanner id = new Scanner(System.in);
}
// Method
public String toString(String name, int id) {
System.out.print(id + " - " + name);
return null;
}
}
The errors that I get, are saying that my methods and constructors are undefined.
A constructor creates ("constructs") a new object. You can then call methods against that object.
Here's a simple object:
public class MyObject {
private int id;
private String name;
public MyObject(int id, String name) {
this.id = id;
this.name = name;
}
// Other methods here, for example:
public void print() {
System.out.println(id + " " + name);
}
}
You would call this constructor like this:
MyObject thing = new MyObject(1, "test");
And then you could call its method like this:
thing.print();
So for your example, what you'd do in your main method is first prompt the user for id and name, then create an object using a constructor, and then call a method on the constructor.
public class ConstructorTest {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// get the id and name from the scanner (I would suggest using prompts)
String name = in.nextLine();
int id = in.nextInt();
// create an object:
ConstructorTest myObject = new ConstructorTest(id, name);
// call the method:
String myString = myObject.toString();
// print the result:
System.out.println(myString);
}
// private variables, effectively the "properties" stored by the object:
private int id;
private String name;
// constructor:
public ConstructorTest(int id, String name) {
this.id = id;
this.name = name;
}
// method
#Override // because this is a method in java.lang.Object and we're overriding it
public String toString() {
return id + " - " + name;
}
}
Try this:
import java.util.Scanner;
public class ConstructorTest {
private int id;
private String name;
public static void main(String[] args) {
String name = args[0];
int id = Integer.valueOf(args[1]);
ConstructorTest ct = new ConstructorTest(name, id);
System.out.println(ct);
}
public ConstructorTest(String n, int i) {
this.id = i;
this.name = n;
}
// Method
public String toString() {
return String.format("%d - %s", id, name);
}
}
Never, ever put I/O in a constructor.
I'm working with Spring Boot 2.0RC2 and in the documentation I read you can return a projection of an entity instead of the entity as a whole when calling the Repository. This is working fine in case I use a String in my Entity but not when I use an embedded value objects.
Let's say I have the Product entity:
#Entity
#Table(name = "t_product")
public class Product extends BaseEntity {
#Column(nullable = false)
private String name;
private Product() {}
private Product(final String name) {
this.name = name;
}
public static Result<Product> create(#NonNull final String name) {
return Result.ok(new Product(name));
}
public String getName() {
return name;
}
public void setName(#NonNull final String name) {
this.name = name;
}
}
The BaseEntity simply holds the id, created and updated attributes.
I have my projection interface called ProductSummary:
interface ProductSummary {
String getName();
Long getNameLength();
}
And in my ProductRepository I have the following method that returns the ProductSummary:
public interface ProductRepository extends JpaRepository<Product, Long> {
#Query(value = "SELECT p.name as name, LENGTH(p.name) as nameLength FROM Product p WHERE p.id = :id")
ProductSummary findSummaryById(#Param("id") Long id);
}
This works perfectly fine. Now let's say I am doing DDD and instead of using a String to represent the name attribute in the Product entity, I want to use a value object called Name:
#Embeddable
public class Name implements Serializable {
public static final int MAX_NAME_LENGTH = 100;
#Column(nullable = false, length = Name.MAX_NAME_LENGTH)
private String value;
private Name() {}
private Name(final String value) {
this.value = value;
}
public static Result<Name> create(#NonNull final String name) {
if (name.isEmpty()) {
return Result.fail("Name cannot be empty");
}
if (name.length() > MAX_NAME_LENGTH) {
return Result.fail("Name cannot be longer than " + MAX_NAME_LENGTH + " characters");
}
return Result.ok(new Name(name));
}
public String getValue() {
return value;
}
}
I change my Product entity to:
#Entity
#Table(name = "t_product")
public class Product extends BaseEntity {
#Embedded
private Name name;
private Product() {}
private Product(final Name name) {
this.name = name;
}
public static Result<Product> create(#NonNull final Name name) {
return Result.ok(new Product(name));
}
public Name getName() {
return name;
}
public void setName(final Name name) {
this.name = name;
}
}
And in the ProductSummary I change the return type from String to Name.
When I run that I always get the exception:
Caused by: java.lang.IllegalAccessError: tried to access class com.acme.core.product.ProductSummary from class com.sun.proxy.$Proxy112
Can I make this work or am I missing some restriction which doesn't allow this?
If you wish to get the complete Name field(not a particular field in Name class), then you need to create another interface like ProductSummary.
interface ProductSummary {
NameSummary getName();
interface NameSummary {
String getValue();
}
}
No need to change anything in your repository.
It is quite clearly documented here
And make sure your interfaces and the methods are public.
I am trying to access class members of different class i.e.,getDetails() from student as well as customer class using Object class Reference variable. But it looks like its not working. Please look into this easy code and help me out how to access the getDetails() using Object class ob[0] and ob[1]
class Customer
{
int custId;
String name;
Customer(String name, int custId)
{
this.custId = custId;
this.name = name;
}
public void getDetails()
{
System.out.println(this.custId+" : "+this.name);
}
}
class Student
{
int roll;
String name;
Student(String name, int roll)
{
this.name = name;
this.roll = roll;
}
public void getDetails()
{
System.out.println(this.roll+" : "+this.name);
}
public static void main(String []args)
{
Object[] ob = new Object[2];
ob[0] = new Student("Vishal", 041);
ob[1] = new Customer("Xyz" , 061);
ob[0].getDetails();
ob[1].getDetails();
}
}
Try creating a common interface that declares the method getDetails. Something like this:
public interface Person {
public void getDetails();
}
Let Student and Customer implement the interface. Then declare the array like this:
Person ent[] ob = new Person[2];
....
this is my current code to store rooms(it compiles fine) but in the UML there is a variable called addEquipment and there is also another class called Equipment to be defined. I'm having trouble wrapping my head around what I'm supposed to do with this. Am I supposed to create and call an object called Equipment? what goes in addEquipment?
public class Room {
//begin variable listing
private String name;
private int id;
private int capacity;
private String equipmentList;
//begins get methods for variables
public String getName(){
return name;
}
public int getID(){
return id;
}
public int getCapacity(){
return capacity;
}
public String getEquipmentList(){
return equipmentList;
}
// Set the variables
public void setName(String aName){
name=aName;
}
public void setID(int anID){
id=anID;
}
public void setCapacity(int aCapacity){
capacity=aCapacity;
}
public void setEquipmentList(String anEquipmentList){
equipmentList=anEquipmentList;
}
public String addEquipment(String newEquipment, String currentEquipment){
}
//Create room object
public Room(int capacity, String equipmentList) {
setCapacity(capacity);
setEquipmentList(equipmentList);
}
//Convert variables to string version of room
public String toString(){
return "Room "+name+", capacity: "+capacity+", equipment: "+getEquipmentList();
}
}
You can create a new class Equipment and modify your attribute equipmentList to be a List:
public class Equipment {
private String name;
public Equipment(String name) {
this.name = name;
}
}
public class Room {
//begin variable listing
private String name;
private int id;
private int capacity;
private List<Equipment> equipmentList = new ArrayList<Equipment>();
//begins get methods for variables
public String getName(){
return name;
}
public int getID(){
return id;
}
public int getCapacity(){
return capacity;
}
public List<Equipment> getEquipmentList(){
return equipmentList;
}
// Set the variables
public void setName(String aName){
name=aName;
}
public void setID(int anID){
id=anID;
}
public void setCapacity(int aCapacity){
capacity=aCapacity;
}
public void setEquipmentList(List<Equipment> anEquipmentList){
equipmentList=anEquipmentList;
}
public String addEquipment(String newEquipment, String currentEquipment){
Equipment oneEquipment = new Equipment(newEquipment);
equipmentList.add(oneEquipment);
}
//Create room object
public Room() {
setCapacity(capacity);
setEquipmentList(equipmentList);
}
//Convert variables to string version of room
public String toString(){
String capacity=String.valueOf(getCapacity());
String room = "Room "+name+", capacity: "+capacity+", equipment: "+getEquipmentList();
return room;
}
}
In the method addEquipment, you can create a new Equipment and add it to equipmentList, like code above.
An Equipment class could be anything. Lets assume the "Equipment"-class has a String called "name" as it's attribute
public class Equipment {
String name;
public Equipment( String name) {
this.name = name;
}
public String getName() {
return this.name
}
}
When you extend your Room class by the requested "addEquipment" method, you can do something like this.
public class Room {
... // Your code
private int equipmentIndex = 0;
private Equipment[] equipment = new Equipment[10]; // hold 10 Equipment objects
public void addEquipment( Equipment eq ) {
if ( equipmentIndex < 10 ) {
equipment[ equipmentIndex ] = eq;
equipmentIndex++;
System.out.println("Added new equipment: " + eq.getName());
} else {
System.out.println("The equipment " + eq.getName() + " was not added (array is full)");
}
}
}
Now when you call
room.addEquipment( new Equipment("Chair") );
on your previously initialized object of the Room-class, you will get
"Added new equipment: Chair"
Hope this helps a bit.
PS: The code is untestet (maybe there hides a syntax error somewhere)
I'm just working through a few things as practice for an exam I have coming up, but one thing I cannot get my head round, is using a variable that belongs to one class, in a different class.
I have a Course class and a Student class. Class course stores all the different courses and what I simply want to be able to do is use the name of the course, in class Student.
Here is my Course class:
public class Course extends Student
{
// instance variables - replace the example below with your own
private Award courseAward;
private String courseCode;
public String courseTitle;
private String courseLeader;
private int courseDuration;
private boolean courseSandwich;
/**
* Constructor for objects of class Course
*/
public Course(String code, String title, Award award, String leader, int duration, boolean sandwich)
{
courseCode = code;
courseTitle = title;
courseAward = award;
courseLeader = leader;
courseDuration = duration;
courseSandwich = sandwich;
}
}
And here is Student:
public class Student
{
// instance variables - replace the example below with your own
private int studentNumber;
private String studentName;
private int studentPhone;
private String studentCourse;
/**
* Constructor for objects of class Student
*/
public Student(int number, String name, int phone)
{
studentNumber = number;
studentName = name;
studentPhone = phone;
studentCourse = courseTitle;
}
}
Am I correct in using 'extends' within Course? Or is this unnecessary?
In my constructor for Student, I am trying to assign 'courseTitle' from class Course, to the variable 'studentCourse'. But I simply cannot figure how to do this!
Thank you in advance for your help, I look forward to hearing from you!
Thanks!
Am I correct in using 'extends' within Course? Or is this unnecessary?
Unfortunately not, if you want to know whether your inheritance is correct or not, replace extends with is-a. A course is a student? The answer is no. Which means your Course should not extend Student
A student can attend a Course, hence the Student class can have a member variable of type Course. You can define a list of courses if your model specifies that (a student can attend several courses).
Here is a sample code:
public class Student{
//....
private Course course;
//...
public void attendCourse(Course course){
this.course = course;
}
public Course getCourse(){
return course;
}
}
Now, you can have the following:
Student bob = new Student(...);
Course course = new Course(...);
bob.attendCourse(course);
I assume a Course is not a Student, so inheritance between those classes is probably a bad idea.
You have to declare them public.
A better way is the keep them private, and code a public getter for that variable. for example:
public Award getCourseAward(){
return this.courseAward;
}
Course should not extend Student. If you want to access the courseTitle field of Course, you need to pass a reference to a Course object to the Student and then do course.CourseTitle.
You cannot access private attributes of a class from another, this is one of the main principles of OOP: encapsulation. You have to provide access method to those attribute, you want to publish outside the class. The common approach is setter/getters - getters only, if you want to have your class immutable. Look here: http://en.wikipedia.org/wiki/Mutator_method#Java_example
It does not make sense to arbitrarily extend classes. Student is not a Course or vice versa, so you cannot extend them like that.
What you need to do is:
create a Course first:
Course aCourse = new Course(..);
create a Student:
Student aStudent = new Student(..);
assign the Course to the Student:
aStudent.setCourse(aCourse.title);
Extending Student with Couse because they are not of the same kind. Extending one class with another happens when specializing a more general (in a sense) one.
The solution would be to pass courseTitle as an argument of the Student constructor
There should be 3 separate objects here, a Course, a Student, and an Enrollment. An enrollment connects a Student to a Course, a Course has many Students, and a Student can enroll in many courses. None of them should extend each other.
First,
You are extending Student class in Course class, which means, student class gets all the coruse class properties. So, the student class does not have the courseTitle property.
Second, yes, it is unnesessary - you need to do the following:
public class Course
{
private Award courseAward;
private String courseCode;
public String courseTitle;
private String courseLeader;
private int courseDuration;
private boolean courseSandwich;
public Course(String code, String title, Award award, String leader, int duration, boolean sandwich)
{
courseCode = code;
courseTitle = title;
courseAward = award;
courseLeader = leader;
courseDuration = duration;
courseSandwich = sandwich;
}
}
public class Student
{
private int studentNumber;
private String studentName;
private int studentPhone;
// This is where you keep the course object associated to student
public Course studentCourse;
public Student(int number, String name, int phone, Course course)
{
studentNumber = number;
studentName = name;
studentPhone = phone;
studentCourse = course;
}
}
Example usage would be something like this:
Course course = new Course("ASD", "TITLE", null, "ME", 50, true);
Student student = new Student(1, "JOHN", "5551234", course);
And then, get the course information you need from student via, i.e.:
student.studentCourse.courseTitle;
Since now student.studentCourse will be a course object with all of its properties.
Cheers,
Maybe you do not need to add the course name to student. What I would do is add Students to some datastructure in Course. This is cleaner and reduces the coupling between Course and Student. This would also allow you to have Students being in more than one course. For example:
public class Course extends Student{
private Award courseAward;
private String courseCode;
public String courseTitle;
private Student courseLeader;//change to a student Object
private int courseDuration;
private boolean courseSandwich;
private Set<Student> students;//have course hold a collection of students
/**
* Constructor for objects of class Course
*/
public Course(String code, String title, Award award, Student leader, int duration, boolean sandwich){
courseCode = code;
courseTitle = title;
courseAward = award;
courseLeader = leader;
courseDuration = duration;
courseSandwich = sandwich;
this.students=new HashSet<Student>();
}
public boolean addStudent(Student student){
return students.add(student);
}
public Set<Student> getStudents(){
return students;
}
}
As mentioned, stay away from the "extends" for this. In general, you shouldn't use it unless the "is-a" relationship makes sense.
You should probably provide getters for the methods on the Course class:
public class Course {
...
public String getTitle() {
return title;
}
}
And then if the Student class needs that, it would somehow get a hold of the course (which is up to you in your design), and call the getter:
public class Student {
private Set<Course> courses = new HashSet<Course>();
public void attendCourse(Course course) {
courses.add(course);
}
public void printCourses(PrintStream stream) {
for (Course course : courses) {
stream.println(course.getTitle());
}
}
}
Here below find out the solution of your problem and if you want to check below code on your machine then create a file named Test.java and paste the below codes:
package com;
class Course
{
private Award courseAward;
private String courseCode;
public String courseTitle;
private String courseLeader;
private int courseDuration;
private boolean courseSandwich;
public Course(String code, String title, Award award, String leader, int duration, boolean sandwich)
{
courseAward = award;
courseCode = code;
courseTitle = title;
courseLeader = leader;
courseDuration = duration;
courseSandwich = sandwich;
}
public Award getCourseAward() {
return courseAward;
}
public void setCourseAward(Award courseAward) {
this.courseAward = courseAward;
}
public String getCourseCode() {
return courseCode;
}
public void setCourseCode(String courseCode) {
this.courseCode = courseCode;
}
public String getCourseTitle() {
return courseTitle;
}
public void setCourseTitle(String courseTitle) {
this.courseTitle = courseTitle;
}
public String getCourseLeader() {
return courseLeader;
}
public void setCourseLeader(String courseLeader) {
this.courseLeader = courseLeader;
}
public int getCourseDuration() {
return courseDuration;
}
public void setCourseDuration(int courseDuration) {
this.courseDuration = courseDuration;
}
public boolean isCourseSandwich() {
return courseSandwich;
}
public void setCourseSandwich(boolean courseSandwich) {
this.courseSandwich = courseSandwich;
}
}
class Student
{
private int studentNumber;
private String studentName;
private int studentPhone;
private Course studentCourse;
/**
* Constructor for objects of class Student
*/
public Student(int number, String name, int phone, Course course)
{
studentNumber = number;
studentName = name;
studentPhone = phone;
studentCourse = course;
}
public int getStudentNumber() {
return studentNumber;
}
public void setStudentNumber(int studentNumber) {
this.studentNumber = studentNumber;
}
public String getStudentName() {
return studentName;
}
public void setStudentName(String studentName) {
this.studentName = studentName;
}
public int getStudentPhone() {
return studentPhone;
}
public void setStudentPhone(int studentPhone) {
this.studentPhone = studentPhone;
}
public Course getStudentCourse() {
return studentCourse;
}
public void setStudentCourse(Course studentCourse) {
this.studentCourse = studentCourse;
}
}
class Award{
private long awardId;
private String awardName;
Award(long awardId, String awardName){
this.awardId = awardId;
this.awardName = awardName;
}
public long getAwardId() {
return awardId;
}
public void setAwardId(long awardId) {
this.awardId = awardId;
}
public String getAwardName() {
return awardName;
}
public void setAwardName(String awardName) {
this.awardName = awardName;
}
}
public class Test{
public static void main(String ar[]){
// use your all classes here
}
}