Skip to content

Instantly share code, notes, and snippets.

@datduyng
Forked from cbourke/Demo.java
Created November 6, 2018 20:18
Show Gist options
  • Select an option

  • Save datduyng/f39c2d263da3eafbd4d51ff79f3982cc to your computer and use it in GitHub Desktop.

Select an option

Save datduyng/f39c2d263da3eafbd4d51ff79f3982cc to your computer and use it in GitHub Desktop.
auto-posted gist
package cse.unl;
import java.time.LocalDate;
public class Demo {
public static void main(String args[]) {
LocalDate dateOfBirth = LocalDate.of(1990, 7, 9);
Student s1 = new Student(35140602, "Chris", "Bourke", 4.0, dateOfBirth);
Student s2 = new Student(1234, "Scott", "Frost", 2.6, dateOfBirth);
Student t = new Student(s1, 4.0);
System.out.println(s1);
System.out.println(s2);
System.out.println(t);
if(s1 == t) {
System.out.println("Equal!");
} else {
System.out.println("NOT Equal!");
}
if(s1.equals(t)) {
System.out.println("Equal!");
} else {
System.out.println("NOT Equal!");
}
}
}

CSCE 155H - Computer Science I - Honors

Encapsulation

Structures & Objects


  • Built-in primitive types (int, double, char) are limiting: not everything is a number or character
  • Real-world entities are made up of multiple aspects (data)
  • Example: Lab 10: sorting teams
    • Kept a lot of different, but related data in different
    • Every swap required a swap of every array
    • Very easy to screw up the book keeping
    • Very inconvenient to treat related pieces of data as unrelated
  • Encapsulation:
    1. The grouping of data
    2. The protection of data
    3. The grouping of functionality that acts on that data

Encapsulation in C

  • C only provides #1: "weak encapsulation", the grouping of data
  • C provides weak encapsulation through structures
  • Syntax:
typedef struct {
  int day;
  int month;
  int year;
} Date;

typedef struct {
  int nuid;
  char *firstName;
  char *lastName;
  double gpa;
  Date dateOfBirth;
} Student;
  • In general, the order of the individual "member variables" does not matter
  • However, the order that you declare structures does matter: you cannot use a structure within another structure unless it is declared first
  • When a structure "owns" an instance of another structure, it is called composition
  • Typically, structures are declared in header files, student.h (example)
  • Naming conventions:
    • UpperCamelCasing for structure names
    • lowerCamelCasing for "member" variables
  • each "field" or "member variable" or "component" is separated by a semicolon (one to a line)

Using Structures

  • Once declared, you can create a structure like any other variable
Student me;
me.nuid = 35140602;

me.lastName = (char *) malloc(sizeof(char) * 7);
strcpy(me.lastName, "Bourke");
me.firstName = (char *) malloc(sizeof(char) * 6);
strcpy(me.firstName, "Chris");
me.gpa = 4.0;
me.dateOfBirth.day = 9;
me.dateOfBirth.month = 7;
me.dateOfBirth.year = 1990;
  • Use the dot operator to access member fields

Factory Functions

  • Creating complex structures is tedious and error prone, so it is generally good to write "constructor" or "factory" functions
Student * createStudent(int nuid,
              char * firstName,
              char * lastName,
              double gpa,
              Date dateOfBirth) {
  Student *s = (Student *) malloc(1 * sizeof(Student));

  s->nuid = nuid;
  s->gpa = gpa;
  s->dateOfBirth = dateOfBirth;

  s->firstName = (char*)malloc(sizeof(char) * (strlen(firstName)+1));
  strcpy(s->firstName, firstName);
  s->lastName = (char*)malloc(sizeof(char) * (strlen(lastName)+1));
  strcpy(s->lastName, lastName);

  //this would only be a shallow copy:
  //s->firstName = firstName;

  return s;
}

//...
Date dateOfBirth = {7, 9, 1990};
Student *me = createStudent(35140602, "Chris", "Bourke",
4.0, {7, 9, 1990});

Encapsulation in Java: Class-based objects

  • Demonstration using Eclipse
  • An object is an entity with identity, state, and behavior
    • Identity: a way to distinguish one object from another (either == or defining an equals() method)
    • State: an object's member variables whose scope is limited to an instance of an object
    • Behavior: methods that act on an object's state belong in the object
  • Java is an OOP language that uses classes to represent objects
  • Naming conventions
    • Name of a class uses UpperCamelCasing
    • Member variables and member methods use lowerCamelCasing (variables are nouns, methods are verbs)
    • Member variables are declared by not using the static keyword (static means that a variable or method belong to the class and not to instances of the class)
  • To create new instances of a class you "instantiate" a new object using the new keyword which invokes a constructor method
    • By default all objects have a default no-argument constructor
    • You can define any number of custom constructors: a constructor that takes all member variables, a constructor that only takes a few, or a copy constructor
    • By default, any member variable that is not set has a default value of 0, false or null depending on its type
    • Its best practice to always reuse existing objects (String, LocalDate, etc.): this is composition
    • Don't over-engineer your objects:
      • First name/last name: don't create a Name class
      • An Address may have a street, city, state, zip, but each one of these may not be decomposable further (ie don't define a State, City object, etc. UNLESS you really need to)
    • YAGNI: You Ain't Gonna Need It

Visibility

  • You can achieve the #2 of encapsulation (protection of data) using visibility keywords

    • private: only the class and its subclasses (as well as other instances) can "see" the variables
    • protected: only the class and its subclasses can see the variable
    • The absence of any keyword makes the variable "package protected": any class in the same package can see the variable
    • public: ANY piece of code can see the variable
  • In general you should prefer the most conservative visibility (private) unless you have a Very Good Reason to do otherwise

  • You should prefer to make all member variables private and control access through constructors and/or getters/setters

  • The this keyword allows you to access an instance's variables and methods ("Open Recursion")

Arrays of Structures (in C)

  • Often you need to create entire collections (arrays) of structures
int n = 10;
//create an array of 10 integers:
int *arr = (int *) malloc(n * sizeof(int));
arr[0] = 10;

//create an array of 10 Students:
Student *roster = (Student *) malloc(n * sizeof(Student));
//memory leak: roster[0] = *createStudent(...);
Student *s = createStudent(...);
roster[0] = *s;
free(s);

Arrays of Objects in Java

  • Arrays suck, use dynamic data structures like Lists, Sets, Maps, etc.
Student s1 = new Student(35140602, "Chris", "Bourke", 4.0, dateOfBirth);
Student s2 = new Student(1234, "Scott", "Frost", 2.6, dateOfBirth);
List<Student> roster = new ArrayList<Student>();
roster.add(s1);
roster.add(s2);
roster.add(new Student(...));
roster.add(s1); //lists allow duplicates!

Set<Student> roster2 = new HashSet<Student>();
roster.add(s1);
roster.add(s2);
roster.add(s1); //duplicate, it will have no effect
//**** it will have no effect assuming that we've defined
//the equals() and hashCode() methods

Map<Integer, Student> nuidMap = new HashMap<Integer, Student>();
nuidMap.put(s1.getNuid(), s1);
nuidMap.put(s2.getNuid(), s2);

Misc

  • Alternatively in C, you can design an "initializer" function
  • A factory function creates a new (dynamically allocated) structure
void initStudent(Student *s, int nuid, const char * firstName,
                 const char * lastName, double gpa) {
  s->nuid = nuid;
  s->gpa = gpa;
  //TODO: make a deep copy instead!
  s->firstName = firstName;
  //TODO: make a deep copy instead!
  s->lastName = lastName;
  return;
}

To String functions in C

  • Create a function that creates a string representation of a Student structure.
char * studentToString(const Student *s) {

  char temp[1000];
  sprintf(temp, "%s, %s (%08d) %.2f", s->lastName, s->firstName, s->nuid, s->gpa);
  char *str = (char *) malloc( (strlen(temp) + 1) * sizeof(char) );
  strcpy(str, temp);
  return str;
}









package cse.unl;
import java.time.LocalDate;
public class Student {
private int nuid;
private String firstName;
private String lastName;
private double gpa;
private LocalDate dateOfBirth;
//TODO: add support for an Address
public Student(int nuid, String firstName, String lastName, double gpa, LocalDate dateOfBirth) {
super();
this.nuid = nuid;
this.firstName = firstName;
this.lastName = lastName;
this.gpa = gpa;
this.dateOfBirth = dateOfBirth;
}
//copy contructor:
public Student(Student that) {
this.nuid = that.nuid;
this.firstName = that.firstName;
this.lastName = that.lastName;
this.gpa = that.gpa;
this.dateOfBirth = that.dateOfBirth;
}
//copy contructor:
public Student(Student that, double gpa) {
this.nuid = that.nuid;
this.firstName = that.firstName;
this.lastName = that.lastName;
this.gpa = gpa;
this.dateOfBirth = that.dateOfBirth;
}
@Override
public String toString() {
return "Student [nuid=" + nuid + ", firstName=" + firstName + ", lastName=" + lastName + ", gpa=" + gpa
+ ", dateOfBirth=" + dateOfBirth + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((dateOfBirth == null) ? 0 : dateOfBirth.hashCode());
result = prime * result + ((firstName == null) ? 0 : firstName.hashCode());
long temp;
temp = Double.doubleToLongBits(gpa);
result = prime * result + (int) (temp ^ (temp >>> 32));
result = prime * result + ((lastName == null) ? 0 : lastName.hashCode());
result = prime * result + nuid;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Student other = (Student) obj;
if (dateOfBirth == null) {
if (other.dateOfBirth != null)
return false;
} else if (!dateOfBirth.equals(other.dateOfBirth))
return false;
if (firstName == null) {
if (other.firstName != null)
return false;
} else if (!firstName.equals(other.firstName))
return false;
if (Double.doubleToLongBits(gpa) != Double.doubleToLongBits(other.gpa))
return false;
if (lastName == null) {
if (other.lastName != null)
return false;
} else if (!lastName.equals(other.lastName))
return false;
if (nuid != other.nuid)
return false;
return true;
}
public int getNuid() {
return nuid;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public double getGpa() {
return gpa;
}
public LocalDate getDateOfBirth() {
return dateOfBirth;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment