Object orientatted programming and classes

Associate
Joined
19 Jul 2006
Posts
1,847
Really strugling to get my head round OOP.

Im trying to learn Java as well.
Im wanting to do a what i think is a small app. to create usernames from a csv file

If I have 2 files, one a csv file containing firstname , surname and the other is just a wordlist.txt file.

And my output is to a new csv file with firstinitial.surname, firstname,surname,password (from a word list)

I have this so far.

Code:
public class Main {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
      try
      {
         Readfile read = new Readfile();
         read.run();
      }
      // Report any IOExceptions which occur
      catch (IOException IOEx)
      {
         System.out.println("Problems reading file " + IOEx);
      }
   }
}

and then

Code:
import java.io.*;
import java.util.*;
/**
 **
 * 
 */

public class Readfile {

     private FileReader fr;
     private BufferedReader br;
     private PrintWriter pw;

     public void run() throws IOException
    {
        String nextLine;
        Scanner sc = new Scanner(new File("export.csv"));
        while (sc.hasNext())
        {
            nextLine = sc.nextLine();
            System.out.println(nextLine);
        }

        sc.close();
    }

So i can read in from one file and output to the output bar, i take it i will need to make new line an array so i can split the line up with stringtokenizer??

Im old school so not got my head around none linear programming as such.

what kinda classes or methods should i have,

IF you can help thank you so much in advance
 
Last edited:
It is not an example were OOP will shine really. The idea of OOP is to treat things as objects and manipulate them as such. For example, a class "CSVFile" could represent your CSV files by taking in the filename:

CSVFile myCSVFile = new CSVFile("foo.txt");

(the constructor reads the file in memory, into a String[][] array or some other data structure depending on application)

and then you call methods like ...

myCSVFile.getRow(2).getColumn(6);

which would return the data after he 5th comma or an expection if no such data exists.

This way you have an object, the CSVFile which you can pass around and manipulate.

The OOP idea here is that you only know what this CSVFIle object can do for you and what not by having access to its internals via the getRow() and getColumn() methods. If in the future CSV files change for example and use an * instead of , you go in change the method code and everything else works fine.

This is by no means a comprehensive OOP tutorial, I just tried to illustrate some ideas :)
 
Last edited:
Thanks drak3.

I have a good book that explains it in cat and dog speak that i understand but the putting it into practice is another thing.

ok I got this so far
Code:
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package gmailcsvapp;



/**
 *
 * @author 
 */

import java.io.*;
import java.io.FileNotFoundException;
public class Main {

    /**
     * @param args the command line arguments
     */
    
    public static void main(String args[]) throws FileNotFoundException, EmptyFileException
    {
        String importfile = "export.csv";

      try
        {
            Readfile reader1 = new Readfile(importfile);
            while (reader1.iter.hasNext())
           
            {
               System.out.println(reader1.getNextLine()+reader1.password());
            }
        }
        catch (EmptyFileException message){
            System.out.println(importfile + " threw a Empty File Exception; the details were as follows - " + message);
        }
       catch (FileNotFoundException message){
            System.out.println(importfile + "Throw a File Not Found Error");
       }
    }
}

and then this
Code:
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package gmailcsvapp;



import java.io.*;
import java.util.*;

public class Readfile
{
   public File file;
   

   public ArrayList<String> userCollection = new ArrayList<String>();
   public Iterator <String>iter;
   public static final String NONE_LEFT = "";

   

   public Readfile(String filename) throws FileNotFoundException, EmptyFileException
    {
        file = new File(filename);
        Scanner sc = new Scanner(file);

        if(sc.hasNext())
        {
           while(sc.hasNext())
           {
               //assuming that each line only has one word (would add additional logic to split lines here if necessary)
               userCollection.add(sc.nextLine().toLowerCase());
           }

        }
        else
        {
           throw new EmptyFileException(filename +  " contains no words");
        }
        iter = userCollection.iterator();
    }




    public String getNextLine()
    {
        if(iter.hasNext())
        {
            return iter.next();
        }
        else
        {
            return NONE_LEFT;
        }
    }


    public ArrayList<String> passwordCollection = new ArrayList<String>();
    public Iterator <String>iterpass;
    public File file1;

       public String password() throws FileNotFoundException, EmptyFileException
   {
       file1 = new File("passwordlist.txt");
       Scanner Pass = new Scanner(file1);

        if(Pass.hasNext())
        {
           while(Pass.hasNext())
           {
               //assuming that each line only has one word (would add additional logic to split lines here if necessary)
               passwordCollection.add(Pass.nextLine().toLowerCase());
           }

        }
        else
        {
           throw new EmptyFileException("passwordlist.txt contains no words");
        }
        iterpass = passwordCollection.iterator();
        long number = (Math.round(Math.random() * 100));
        Random generator = new Random();
        int index = generator.nextInt ( passwordCollection.size() );
        if( index >-1 ) return ( ","+passwordCollection.get(index)+number);



       return (","+iterpass.next()+number);
   }

}

Ignorring the password bit which works, this now prints out, firstname,surname,and a randompassword.

anypointers on getting the fitstinitial.surname at the begining
 
Sorry for the slight thread hijack, but I can't quite get my head round what OOP actually is, all I see is weird diagrams of relationships and talk of objects.

Can someone provide an in-english explanation or example?

***

Here's what I understand so far, if someone would kindly confirm or deny.

So, instead of three variables called FirstName, Surname, and Age, and a function called addUser(FirstName, Surname, Age) which would write to a db for example, you would instead have a class called Person, which would have Firstname, Surname, and Age as variables inside it. It would also have a function addUser inside it.

First you create an instance of it, Person example = new Person, and then do something like example.Firstname = "bob", example.addUser() to assign the variable and then run the function. Amidoingitrite?
 
Here is a solution, it's pretty much completely different to yours. It's a bit more of object oriented solution as drak3 was discussing, take a look.

Essentially the CSVParser class (replaces your Readfile class) is responsible for one thing which is to read a CSV file and perform operations on it, there is no code in that class which deals with usernames or passwords. Likewise the Password Generator class (replaces your main class) does not know anything about dealing with CSV files, it leaves all of that to the CSVParser class.

Below is a representation of the data structure used by the CSVParser class to store the CSV file:

Code:
ArrayList<String> =	{
				[0] => String[] {John,Smith}
				[1] => String[] {James,Bond}
				[2] => String[] {Bob,Brown}
				[3] => String[] {Alice,Green}
				[4] => String[] {Dave,Black}
			}

By the end of the execution, the data structure looks like this:

Code:
ArrayList<String> =	{
				[0] => String[] {j.smith,password90}
				[1] => String[] {j.bond,password39}
				[2] => String[] {b.brown,password54}
				[3] => String[] {a.green,password4}
				[4] => String[] {d.black,password12}
			}

Code:
package gmailcsvapp;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;

public class CSVParser {

	private int rows;
	private int cols;
	private String delim;
	private ArrayList<String[]> data;
	private static final String lineSeparator = System.getProperty("line.separator");
	
	public CSVParser(String file) throws FileNotFoundException, EmptyFileException
	{
		this(file, ",");
	}
	
	public CSVParser(String file, String delim) throws FileNotFoundException, EmptyFileException {
		this.delim = delim;
		data = new ArrayList<String[]>();
		Scanner scan = new Scanner(new File(file));
		while (scan.hasNextLine())
		{
			data.add(scan.nextLine().split(delim));
		}
		rows = data.size();
		if (rows == 0)
		{
			throw new EmptyFileException(file + " (The file specified is empty)");
		}
		cols = data.get(0).length;
	}
	
	public void appendToRow(int index, String str)
	{
		String[] oldRow = getRow(index);
		String[] newRow = Arrays.copyOf(oldRow, oldRow.length+1);
		newRow[newRow.length-1] = str;
		setRow(index, newRow);
	}
	
	public String[] getCol(int index)
	{
		ArrayList<String> col = new ArrayList<String>();
		for (String[] row : data)
		{
			col.add(row[index]);
		}
		String[] ret = new String[col.size()];
		return col.toArray(ret);
	}
	
	public int getColCount()
	{
		return cols;
	}
	
	public String[] getRow(int index)
	{
		return data.get(index);
	}
	
	public int getRowCount()
	{
		return rows;
	}
	
	public void setRow(int index, String[] row)
	{
		data.set(index, row);
	}
	
	public void toFile(String filename) throws FileNotFoundException
	{
		PrintWriter writer = new PrintWriter(new File(filename));
		writer.print(toString());
		writer.close();
	}
	
	public String toString()
	{
		String ret = "";
		for (String[] row : data)
		{
			for (int i = 0; i < row.length-1; i++)
			{
				ret += row[i]+delim;
			}
			ret += row[row.length-1]+lineSeparator;
		}
		return ret;
	}	
}

Code:
package gmailcsvapp;

import java.io.FileNotFoundException;
import java.util.Arrays;
import java.util.Random;

public class PasswordGenerator {

	private CSVParser user;
	private CSVParser pass;
	
	public PasswordGenerator()
	{
		try {
			user = new CSVParser("export.csv");
			pass = new CSVParser("passwordlist.txt");
		} catch (FileNotFoundException e) {
			System.out.println(e.getMessage());
		} catch (EmptyFileException e) {
			System.out.println(e.getMessage());
		}

		generateUsernames();		
		generatePasswords();
		
		try {
			user.toFile("exported.csv");
		} catch (FileNotFoundException e) {
			System.out.println(e.getMessage());
		}
	}
	
	public void generateUsernames()
	{
		for (int i = 0; i < user.getRowCount(); i++)
		{
			String[] row = user.getRow(i);
			String[] newRow = Arrays.copyOfRange(row, 1, row.length);
			String username = row[0].substring(0,1) + "." + row[1];
			newRow[0] = username.toLowerCase();
			user.setRow(i, newRow);
		}
	}
	
	public void generatePasswords()
	{
		for (int i = 0; i < user.getRowCount(); i++)
		{
			user.appendToRow(i, getPassword());	
		}
	}
	
	private String getPassword()
	{
		String[] passwords = pass.getCol(0);
		Random rand = new Random();
		String pass = passwords[rand.nextInt(passwords.length-1)];
		return pass.toLowerCase() + rand.nextInt(100); 
	}
	
	public static void main(String[] args) {
		new PasswordGenerator();
	}
}

There are probably some confusing concepts in this code if you're new to Java but it a lot clearer than the code you posted.
 
Sorry for the slight thread hijack, but I can't quite get my head round what OOP actually is, all I see is weird diagrams of relationships and talk of objects.

Can someone provide an in-english explanation or example?

***

Here's what I understand so far, if someone would kindly confirm or deny.

So, instead of three variables called FirstName, Surname, and Age, and a function called addUser(FirstName, Surname, Age) which would write to a db for example, you would instead have a class called Person, which would have Firstname, Surname, and Age as variables inside it. It would also have a function addUser inside it.

First you create an instance of it, Person example = new Person, and then do something like example.Firstname = "bob", example.addUser() to assign the variable and then run the function. Amidoingitrite?

OOP is a generic term people use nowadays. It is not one concept but rather many concepts. The main idea is that you have many objects that talk to each other instead of serial code, i.e. code that is executed line by line from line 1 to line 100 and then the program stops and says "done".

The simplest and maybe the most popular example is a bank account.

You have a class Account that has 2 variables inside it to keep track of the account balance and the account number. Then methods like, deposit() , widthdraw(), and getBalance().

We create a new accout object Account acc = new Account("123-123-123");

We can then deposit by acc.deposit(100);

and widthdraw by acc.widthdraw(50);

If we then call acc.getBalance(); it will return 50.

As you can see this way we can create many accounts with a different number and each object will have its own internal variables and keep track of the balance. This is "Encapsulation", a concept of OOP. In simple words, keep everything hidden inside the object so nobody can tamper with the balance unless they go through the public methods deposit/widthdraw in which there is code that will check if the account has money in before widthdraw(10000000) for example.

I tried to illustrate using a simple example, but there is much more to it ... google is your friend if you are really interested :)
 
Here is a solution, it's pretty much completely different to yours. It's a bit more of object oriented solution as drak3 was discussing, take a look.

Essentially the CSVParser class (replaces your Readfile class) is responsible for one thing which is to read a CSV file and perform operations on it, there is no code in that class which deals with usernames or passwords. Likewise the Password Generator class (replaces your main class) does not know anything about dealing with CSV files, it leaves all of that to the CSVParser class.

Below is a representation of the data structure used by the CSVParser class to store the CSV file:

Code:
ArrayList<String> =	{
				[0] => String[] {John,Smith}
				[1] => String[] {James,Bond}
				[2] => String[] {Bob,Brown}
				[3] => String[] {Alice,Green}
				[4] => String[] {Dave,Black}
			}

By the end of the execution, the data structure looks like this:

Code:
ArrayList<String> =	{
				[0] => String[] {j.smith,password90}
				[1] => String[] {j.bond,password39}
				[2] => String[] {b.brown,password54}
				[3] => String[] {a.green,password4}
				[4] => String[] {d.black,password12}
			}

Code:
package gmailcsvapp;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;

public class CSVParser {

	private int rows;
	private int cols;
	private String delim;
	private ArrayList<String[]> data;
	private static final String lineSeparator = System.getProperty("line.separator");
	
	public CSVParser(String file) throws FileNotFoundException, EmptyFileException
	{
		this(file, ",");
	}
	
	public CSVParser(String file, String delim) throws FileNotFoundException, EmptyFileException {
		this.delim = delim;
		data = new ArrayList<String[]>();
		Scanner scan = new Scanner(new File(file));
		while (scan.hasNextLine())
		{
			data.add(scan.nextLine().split(delim));
		}
		rows = data.size();
		if (rows == 0)
		{
			throw new EmptyFileException(file + " (The file specified is empty)");
		}
		cols = data.get(0).length;
	}
	
	public void appendToRow(int index, String str)
	{
		String[] oldRow = getRow(index);
		String[] newRow = Arrays.copyOf(oldRow, oldRow.length+1);
		newRow[newRow.length-1] = str;
		setRow(index, newRow);
	}
	
	public String[] getCol(int index)
	{
		ArrayList<String> col = new ArrayList<String>();
		for (String[] row : data)
		{
			col.add(row[index]);
		}
		String[] ret = new String[col.size()];
		return col.toArray(ret);
	}
	
	public int getColCount()
	{
		return cols;
	}
	
	public String[] getRow(int index)
	{
		return data.get(index);
	}
	
	public int getRowCount()
	{
		return rows;
	}
	
	public void setRow(int index, String[] row)
	{
		data.set(index, row);
	}
	
	public void toFile(String filename) throws FileNotFoundException
	{
		PrintWriter writer = new PrintWriter(new File(filename));
		writer.print(toString());
		writer.close();
	}
	
	public String toString()
	{
		String ret = "";
		for (String[] row : data)
		{
			for (int i = 0; i < row.length-1; i++)
			{
				ret += row[i]+delim;
			}
			ret += row[row.length-1]+lineSeparator;
		}
		return ret;
	}	
}

Code:
package gmailcsvapp;

import java.io.FileNotFoundException;
import java.util.Arrays;
import java.util.Random;

public class PasswordGenerator {

	private CSVParser user;
	private CSVParser pass;
	
	public PasswordGenerator()
	{
		try {
			user = new CSVParser("export.csv");
			pass = new CSVParser("passwordlist.txt");
		} catch (FileNotFoundException e) {
			System.out.println(e.getMessage());
		} catch (EmptyFileException e) {
			System.out.println(e.getMessage());
		}

		generateUsernames();		
		generatePasswords();
		
		try {
			user.toFile("exported.csv");
		} catch (FileNotFoundException e) {
			System.out.println(e.getMessage());
		}
	}
	
	public void generateUsernames()
	{
		for (int i = 0; i < user.getRowCount(); i++)
		{
			String[] row = user.getRow(i);
			String[] newRow = Arrays.copyOfRange(row, 1, row.length);
			String username = row[0].substring(0,1) + "." + row[1];
			newRow[0] = username.toLowerCase();
			user.setRow(i, newRow);
		}
	}
	
	public void generatePasswords()
	{
		for (int i = 0; i < user.getRowCount(); i++)
		{
			user.appendToRow(i, getPassword());	
		}
	}
	
	private String getPassword()
	{
		String[] passwords = pass.getCol(0);
		Random rand = new Random();
		String pass = passwords[rand.nextInt(passwords.length-1)];
		return pass.toLowerCase() + rand.nextInt(100); 
	}
	
	public static void main(String[] args) {
		new PasswordGenerator();
	}
}

There are probably some confusing concepts in this code if you're new to Java but it a lot clearer than the code you posted.

RobH's code above is what I had in mind as well. OOP is about keeping things separate and interchangeable. Using this approach, as RobH mentioned you can replace the CSVParser any time with another type of parser and file format. For example, an Excel spreadsheet with an ExcelParser. The Password generator only expects the method getRow() of data to be available. What is really going on inside the method is none of its business.
 
Thank you so much for that, I slowly understanding it,

Got it to do everything it needs to do :)

How difficult would it be to now use some kind of file selector to select a file to open and a file name to export it to rather than it been hard coded
 
Last edited:
One major principle of OO is polymorphism and Abstraction.

Essentially its the ability to "genralise" your code, allowing you to write code that is easy to maintain and extend.

A short example using your parser might be to firstly :

Create an "parser" abstraction. This might be a interface or abstract "base" class e.g.

Code:
public interface IFileParser
{
     Void ParseFile(string fileName);
}

So I now have a FileParser "abstraction" that allows me to create different types of parsers easily e.g.

Code:
public class CSVFileParser : IFileParser
{
      Public void ParseFile(string fileName)
      {
            //Do CSV file stuff here
       }
}

public class ExcelFileParser : IFileParser
{
      Public void ParseFile(string fileName)
      {
            //Do Excel file stuff here
       }
}
}

The calling code Doesn`t care about the actual implementations as it uses the "abstraction"

Code:
Public void DoSomeParsing()
{
     iFileParser aParser = GetCSVFileParser(); //You would use a "factory" here to return the appropriate parser
    aParser.ParseFile("C:\foo.txt");
}

as you can see the above method doesn`t need to know what type of parser it is using, and therefore you can replace or extend the parsers without having to change the calling code.
 
Last edited:
Back
Top Bottom