code does not compile

Working on some Java excercises, taking a course as a senior observer at a local community college.
I understand the words about what is wrong ":there must be class-scope data fields, declared within the class, but not within any method."  but do not know how to fix.

******* code *********
 //*Create Person Class
class Person {
      public static void main(String[] args) {
          //* Declare first, middle and last name variables
      String firstName;
      String middleName ;
      String lastName;
      //* Force caps first for each name
      //* p1 get substring of firstName, starting at position 0 going out 1 character, convert to upper case.  Get substring starting at positio 1 for the entire length and convert to lower
      String properFirst = (firstName.substring(0,1).toUpperCase()+ firstName.substring(1, firstName.length()).toLowerCase());
      String properMiddle = (middleName.substring(0,1).toUpperCase()+ middleName.substring(1, middleName.length()).toLowerCase());
      String properLast = (lastName.substring(0,1).toUpperCase()+ lastName.substring(1, lastName.length()).toLowerCase()) ;
      // * Concatenate the strings for output
      String p1 = properFirst.concat(properLast);
      String p2 = properFirst.concat(properMiddle);
      String p3 = p2.concat(properLast);
      // * Put Constructor here
      //* Create first/last, first/middle/last and last/middle/first combinations for p# strings in main
      Person() {
            String p1=(properFirst+properLast);
            String p2=(properFirst+properMiddle+properLast);
            String p3=(properLast+properMiddle+properFirst);
            }
      }
 }
LVL 16
glenn_1984Asked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Doc_McAlisterCommented:
Your constructor should not be inside your main block:

Person
{
    main
    {
         Person()
         {
             // NO! not a child of main!!
         }
     }
}
0
Doc_McAlisterCommented:
Also, you are trying to parse the names before putting anything in them?  Or did you cut out the part where it gets populated before posting?

And if your constructor is outside your main function, it can not see variables declared inside your main function like properfirst.  

I usually make the class with the "main" function in a package contain that and nothing else.  Main will then instantiate instances of the other classes in the package as needed.  So I'd have a class "main" with a Main function that instantiate my other class, Person, and uses it.

0
murugesandinsShell_script Automation /bin/bash /bin/bash.exe /bin/ksh /bin/mksh.exe AIX C C++ CYGWIN_NT HP-UX Linux MINGW32 MINGW64 SunOS Windows_NTCommented:
javac  Person.java

java Person

Example code in the file Person.java:
import java.io.*;
import java.lang.*;
class base
{
                String firstName;
                String middleName;
                String lastName;
                base(String a,String b,String c)
                {
                        firstName=a;
                        middleName=b;
                        lastName=c;
                }
};
 
public class Person
{
        public static void main(String[] args)
        {
                base b;
                b=new base("FIRST","MIDDLE","LAST");
                String properFirst;
                String properMiddle;
                String properLast;
                properFirst = (b.firstName.substring(0,1).toUpperCase()+ b.firstName.substring(1, b.firstName.length()).toLowerCase());
                properMiddle = (b.middleName.substring(0,1).toUpperCase()+ b.middleName.substring(1, b.middleName.length()).toLowerCase());
                properLast = (b.lastName.substring(0,1).toUpperCase()+ b.lastName.substring(1, b.lastName.length()).toLowerCase()) ;
                String p1 = properFirst.concat(properLast);
                String p2 = properFirst.concat(properMiddle);
                String p3 = p2.concat(properLast);
                System.out.println(p1);
                System.out.println(p2);
                System.out.println(p3);
        }
};

Open in new window

0
Cloud Class® Course: C++ 11 Fundamentals

This course will introduce you to C++ 11 and teach you about syntax fundamentals.

glenn_1984Author Commented:
Great responses.  Thanks.

The attached code does compile (removed public Person)
However, TestProject1.java does not compile -- see below

murugesandins:
Sorry, I should have clarified that this will be linked with the main code below and the public static void statement will be removed from Person.java.
On the imports, the class has not gotten to that part yet.  I will look it up, however.
Would removing this line "public static void main(String[] args)
"from your code work with the code below?

Doc:
here is the main that I need to relate to.
It has the data.
I was not concerned with running (i.e. no data), just compiling.
When linked the public static void etc. will be removed from Person.java
I commented out the Address info for the test.

public class TestProject1 {
    public static void main( String args[ ] ) {
       // Address a1 = new Address( );
       // Address a2 = new Address( "123-01", "Roosevelt Ave.", "Flushing", "ny", 11368 );
       
       // System.out.println( a1 );
       // System.out.println( a2 );
       
      //  System.out.println( );
       
        Person p1 = new Person( "david", "WRIGHT" );
        Person p2 = new Person( "George", "Thomas", "Seaver" );
        Person p3 = new Person( "Orlando", "el duque", "herNANdez" );
       
        System.out.println( p1 );
        System.out.println( p2 );
        System.out.println( p3 );
    }
}

class Person {
	//* Declare first, middle and last name variables
	//public Person {
	String firstName;
	String middleName ;
	String lastName;
	//* p1 get substring of firstName, starting at position 0 going out 1 character, convert to upper case.  Get substring starting at positio 1 for the entire length and convert to lower
	String properFirst = (firstName.substring(0,1).toUpperCase()+ firstName.substring(1, firstName.length()).toLowerCase());
	String properMiddle = (middleName.substring(0,1).toUpperCase()+ middleName.substring(1, middleName.length()).toLowerCase());
	String properLast = (lastName.substring(0,1).toUpperCase()+ lastName.substring(1, lastName.length()).toLowerCase()) ;
	// * Concatenate the strings for output
	String p1 = properFirst.concat(properLast);
	String p2 = properFirst.concat(properMiddle);
	String p3 = p2.concat(properLast);
	// * Put Constructor here
	//* Create first/last, first/middle/last and last/middle/first combinations for p# strings in main
		Person() {
		String p1=(properFirst+properLast);
		String p2=(properFirst+properMiddle+properLast);
		String p3=(properLast+properMiddle+properFirst);	
			}  //* Person constructor
		//*} //* public Person
	} //* class Person

Open in new window

0
zzynxSoftware engineerCommented:
Maybe this is what you had in mind?
class Person {
 
      //* Declare first, middle and last name variables
      String firstName;
      String middleName ;
      String lastName;
 
      public Person(String firstName, String middleName, String lastName) {
	 this.firstName = firstName;
         this.middleName = middleName;
         this.lastName = lastName;
      }
      public String getFirstLast() {
         return firstName + " " + lastName;
      }
      public String getFullName() {
         return firstName + " " + middleName + " " +lastName;
      }
      public String getReverseFullName() {
         return lastName + " " + middleName + " " + firstName;
      }
 
 
      public static void main(String[] args) {
 
	// Check that there are 3 parameters passed in
        if (args.length < 3) {
          System.out.println("Three arguments needed.")
          return;
        }
	String firstName = arg[0];
        String middleName = arg[1];
        String lastName = arg[2];
 
        String properFirst = (firstName.substring(0,1).toUpperCase()+ firstName.substring(1, firstName.length()).toLowerCase());
        String properMiddle = (middleName.substring(0,1).toUpperCase()+ middleName.substring(1, middleName.length()).toLowerCase());
        String properLast = (lastName.substring(0,1).toUpperCase()+ lastName.substring(1, lastName.length()).toLowerCase()) ;
 
	Person p = new Person(properFirst, properMiddle, properLast);
 
	System.out.println("FirstLast = " + p.getFirstLast());
        System.out.println("FullName = " + p.getFullName());
        System.out.println("ReverseFullName = " + p.getReverseFullName());
      }
}

Open in new window

0
zzynxSoftware engineerCommented:
>> Person p1 = new Person( "david", "WRIGHT" );
If you must be able to write the above then you need an extra constructor:

>> System.out.println( p1 );
If you must be able to write the above, then your Person class needs a method toString()


class Person {
 
      //* Declare first, middle and last name variables
      String firstName;
      String middleName;
      String lastName;
 
      public Person(String firstName, String middleName, String lastName) {
         this.firstName = firstName;
         this.middleName = middleName;
         this.lastName = lastName;
      }
      // Extra constructor (in case of no middle name)
      public Person(String firstName, String lastName) {
         this.firstName = firstName;
         this.lastName = lastName;
      }
      public String toString() {
         return getFullName();
      }
 
      public String getFirstLast() {
         return firstName + " " + lastName;
      }
      public String getFullName() {
         return middleName==null ? getFirstLast() :
                firstName + " " + middleName + " " +lastName;
      }
      public String getReverseFullName() {
         return (new StringBuffer(getFullName())).reverse().toString();
      }
 
 
      public static void main(String[] args) {
 
        // Check that there are 3 parameters passed in
        if (args.length < 3) {
          System.out.println("Three arguments needed.")
          return;
        }
        String firstName = arg[0];
        String middleName = arg[1];
        String lastName = arg[2];
 
        String properFirst = (firstName.substring(0,1).toUpperCase()+ firstName.substring(1, firstName.length()).toLowerCase());
        String properMiddle = (middleName.substring(0,1).toUpperCase()+ middleName.substring(1, middleName.length()).toLowerCase());
        String properLast = (lastName.substring(0,1).toUpperCase()+ lastName.substring(1, lastName.length()).toLowerCase()) ;
 
        Person p = new Person(properFirst, properMiddle, properLast);
 
        System.out.println("FirstLast = " + p.getFirstLast());
        System.out.println("FullName = " + p.getFullName());
        System.out.println("ReverseFullName = " + p.getReverseFullName());
      }
}

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
zzynxSoftware engineerCommented:
Oh, I see:

To compile against this test class

public class TestProject1 {
    public static void main( String args[ ] ) {
        Person p1 = new Person( "david", "WRIGHT" );
        Person p2 = new Person( "George", "Thomas", "Seaver" );
        Person p3 = new Person( "Orlando", "el duque", "herNANdez" );
       
        System.out.println( p1 );
        System.out.println( p2 );
        System.out.println( p3 );
    }
}

you need this Person class:
class Person {
 
      //* Declare first, middle and last name variables
      String firstName;
      String middleName;
      String lastName;
 
      public Person(String firstName, String middleName, String lastName) {
         this.firstName = (firstName.substring(0,1).toUpperCase()+ firstName.substring(1, firstName.length()).toLowerCase());
         if (middleName!=null)
            this.middleName = (middleName.substring(0,1).toUpperCase()+ middleName.substring(1, middleName.length()).toLowerCase());
         this.lastName = (lastName.substring(0,1).toUpperCase()+ lastName.substring(1, lastName.length()).toLowerCase());
      }
      // Extra constructor (in case of no middle name)
      public Person(String firstName, String lastName) {
         this(firstName, null, lastName);
      }
      public String toString() {
         return getFullName();
      }
 
      public String getFirstLast() {
         return firstName + " " + lastName;
      }
      public String getFullName() {
         return middleName==null ? getFirstLast() :
                firstName + " " + middleName + " " +lastName;
      }
      public String getReverseFullName() {
         return (new StringBuffer(getFullName())).reverse().toString();
      }
}

Open in new window

0
glenn_1984Author Commented:
zynx:
Thanks.  But before I use this code I need to understand it.
1. Will this generate the p1, p2, p3 in TestProject1.java?
2.  See my 4 queries in comments, please

     
      //  Line below is a new thought for me.  Couldn't this be done with one constructor and p1, p2, p3, or would that conflict with the MAIN program p1, p2, p3
 // Extra constructor (in case of no middle name)
      //  why public Person() instead of Person()
      public Person(String firstName, String lastName) {

      //what does this line do ?
         this(firstName, null, lastName);

      }
      //  what does next  line do?
      public String toString() {

         return getFullName();
      }
0
zzynxSoftware engineerCommented:
>> But before I use this code I need to understand it.
Of course. No problem.

>> 1. Will this generate the p1, p2, p3 in TestProject1.java?
Yes.

>>        Person p1 = new Person( "david", "WRIGHT" );
>>        Person p2 = new Person( "George", "Thomas", "Seaver" );
>>        Person p3 = new Person( "Orlando", "el duque", "herNANdez" );
In the above see the use of a Person constructor with 3 parameters and one with only 2
(= the situation where the middlename is not given)

I hope you understand that
>>        Person p1 = new Person( "david", "WRIGHT" );
means: "Create an instance of the class Person and call it 'p1'. As parameters I pass "david" (being the first name) and "WRIGHT" being the last name.

[1] & [3]
for the way p2 and p3 are created we just need a Person constructor that takes 3 parameters:

public Person(String firstName, String middleName, String lastName) {
      ....
}

But since in the test class we also see (case p1) that we must be able to call a constructor with 2 parameters only,
we should have one in our Person class.

public Person(String firstName, String lastName) {
   ...
}

Of course we could have written it as:

public Person(String firstName, String middleName, String lastName) {
         this.firstName = (firstName.substring(0,1).toUpperCase()+ firstName.substring(1, firstName.length()).toLowerCase());
         this.lastName = (lastName.substring(0,1).toUpperCase()+ lastName.substring(1, lastName.length()).toLowerCase());
}

But - for maintenance reasons - it is a bad idea to have code duplication. Because if you ever have to change something in the code of the constructor with 3 parameters, you can forget to do the change also in the constructor having 2 parameters.
That's why the body of the constructor taking 2 parameters is just a call of the constructor taking 3 parameters:

this(firstName, null, lastName);

So, on your question "What does this line do?", the answer is "it calls the Person constructor taking 3 parameters and it passes null as the second parameter.

[2] >> //  why public Person() instead of Person()
Answer: see http://java.sun.com/docs/books/tutorial/java/javaOO/accesscontrol.html

[4] >> //  what does next  line do?
The basic java class Object has a method toString() of which the documentation says:
"Returns a string representation of the object.
In general, the toString method returns a string that "textually represents" this object.
The result should be a concise but informative representation that is easy for a person to read.
It is recommended that all subclasses override this method.

The toString method for class Object returns a string consisting of the name of the class of which the object is an instance, the at-sign character `@', and the unsigned hexadecimal representation of the hash code of the object."

So if we don't override the toString() method in the Person class,
writing the lines
>> System.out.println( p1 );
>> System.out.println( p2 );
>> System.out.println( p3 );
in the test class will result in the following less informative output:

Person@1321656
Person@4798766
Person@4679646

If we want a more human readable output, we need to override the toString() method like I did.
In that case the result of that three lines in the test class will be:

David Wright
George Thomas Seaver
Orlando El duque Hernandez

I hope this answers your questions
0
zzynxSoftware engineerCommented:
thanx 4 axxepting

PS.
What answer would - in your opinion - have deserved an A grade?
I thought I was as detailed as possible.
If you are not completely satisfied with an answer, just ask for more explanation.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Java

From novice to tech pro — start learning today.