Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # Structures & Objects
- * Built-in primitive types (`int, double, char`) are limiting: not everything is a number or character
- * Example: Lab 10: sorting teams
- * 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 weak encapsulation, that is, #1 the grouping of data
- * C provides this through the use of structures
- * Syntax for declaring a structure:
- ```c
- typedef struct {
- int year;
- int month;
- int day;
- } Date;
- typedef struct {
- int nuid;
- char * firstName;
- char * lastName;
- Date dateOfBirth;
- double gpa;
- } Student;
- ```
- * In general, structures are declared in a header file `.h`
- * Modern convention: use `UpperCamelCasing` for structure names, `lowerCamelCasing` for structure elements ("fields")
- * Semicolons delimit the fields in a structure
- * structures that use other structures must be declared after the structures they use
- * In general, all functions that use the structure are also included in the same header/source file (`student.h, student.c`)
- ## Using Structures
- * once a structure has been declared, you can use it like any other variable
- * The dot operator allows you to access individual fields in a structure
- ```c
- Student s;
- s.nuid = 12345678;
- s.firstName = (char *) malloc(6 * sizeof(char));
- strcpy(s.firstName, "Chris");
- s.lastName = (char *) malloc(7 * sizeof(char));
- strcpy(s.lastName, "Bourke");
- s.gpa = 3.5;
- s.dateOfBirth.year = 1978;
- s.dateOfBirth.month = 7;
- s.dateOfBirth.day = 9;
- ```
- ## Factory Functions
- * Writing a "factory" function allows you to create new structures easily
- ```c
- /**
- * Returns a pointer to a newly constructed
- * student structure with the given values
- */
- Student * createStudent(int nuid,
- const char * firstName,
- const char * lastName,
- double gpa,
- Date dateOfBirth) {
- Student *s = NULL;
- s = (Student *) malloc(sizeof(Student) * 1);
- //you *could* dereference and then use the dot operator:
- //(*s).nuid = 123456878;
- s->nuid = nuid;
- s->firstName = (char *) malloc( (strlen(firstName)+1) * sizeof(char));
- strcpy(s->firstName, firstName);
- s->lastName = (char *) malloc( (strlen(lastName)+1) * sizeof(char));
- strcpy(s->lastName, lastName);
- s->gpa = gpa;
- s->dateOfBirth.year = dateOfBirth.year;
- s->dateOfBirth.month = dateOfBirth.month;
- s->dateOfBirth.day = dateOfBirth.day;
- return s;
- }
- ...
- Date dayOfBirth;
- dayOfBirth.year = 1978;
- dayOfBirth.month = 7;
- dayOfBirth.day = 9;
- Student *me = createStudent(12345678, "Chris", "Bourke", 3.5, dayOfBirth);
- Student *kyle = createStudent(87654321, "Kyle", "Schwarber", 3.95, TODO);
- ```
- ### Using Structures in Arrays
- * You can create static arrays of structures, but its better to create dynamic arrays
- ```
- int n = 10;
- int *a = (int *) malloc(sizeof(int) * n);
- //create an array of Students:
- Student *roster = (Student *) malloc(sizeof(Student) * n);
- roster[0].nuid = 123455;
- //this dereferences the returned Student pointer so that it can be assigned as the
- // first element in the array
- roster[0] = *createStudent(12345678, "Chris", "Bourke", 3.5, dayOfBirth);
- //alternatively, you could have an array of Student pointers
- //a roster of 10 students
- Student **roster = NULL;
- roster = (Student **) malloc(sizeof(Student *) * 10);
- roster[0] = createStudent(12345678, "Chris", "Bourke", 3.5, dayOfBirth);
- ```
- ### Passing Structures to functions
- * Its always best to pass by reference
- ```c
- /**
- * Prints the given Student structure to the standard
- * output
- */
- void printStudent(const Student *s) {
- //printf("%s, %s (%d) GPA = %.2f\n", s->lastName, s->firstName, s->nuid, s->gpa);
- char *str = studentToString(s);
- printf("%s\n", str);
- free(str);
- return;
- }
- void printRoster(Student *s, int n) {
- int i;
- for(i=0; i<n; i++) {
- printStudent(&s[i]);
- }
- return;
- }
- /**
- * This function takes a student structure
- * and returns a string representation of it
- */
- char * studentToString(const Student *s) {
- //you could add up all characters: int length = strlen(s->firstName) + strlen(s->lastName) + ...
- char temp[1000];
- sprintf(temp, "%s, %s (%d) GPA = %.2f", s->lastName, s->firstName, s->nuid, s->gpa);
- char * result = (char *) malloc( (strlen(temp) + 1) * sizeof(char));
- strcpy(result, temp);
- return result;
- }
- ```
- ## Objects in Java
- * Java is an object-oriented programming language and supports "objects" through the use of classes (it is a class-based OOP language)
- * An *object* is an entity with identity, state, and behavior
- * Identity: a class provides a blue-print for how to create *instances* of an object, each *instance* has identity (it is distinct from other instances)
- * State simply means that a class has *member variables*
- * Behavior: an object may also have *member methods*
- * Example: let's create a student object
- ### Visibility
- * member variables (and methods) can be made:
- * `private` only instances of a class can "see" the variables
- * `protected` only instances and subclasses can see the variables (involves inheritance)
- * `public` any piece of code can see the variables
- * In general, if a piece of code can see a variable, it can change it, this is bad: akin to create global variables
- * It is best practice to make all variables `private` unless there is a very good reason to do so.
- * You still want to interact with the object, so you can define getters and setters (accessor/mutator methods)
- * Advantages:
- * Lack of setters means you can design immutable objects (immutability is a very good thing in multithreaded programming)
- * getters/setters allow for data validation
- * Disadvantages: lotsotyping, solved with an IDE
- * If we make things immutable, how do we set values initially?
- ### Constructor methods
- * Constructor methods have the same name as the class, no return type, but may take any number of arguments
- * Multiple constructors can be defined
- * Constructor methods can be invoked (called) using the `new` keyword
- * If you do not define a constructor, a default, no-argument one will be provided for you, it simply sets all values to default values (0, 0.0, `null`, etc.)
- * The `this` keyword is used to refer to an object's own variables and methods (referred to as "open recursion")
- * If you define a constructor, the default no-argument constructor goes away
- ## Misc
- * The `toString()` method can be overridden/defined for conveniently printing an object in a human-readable format
- * Recall the `static` keyword: it makes a variable or method part of the class rather than instances of the class, it is best to use the `final` keyword to make it a constant (so nothing can change it)
- * One object may contain other objects, this is known as *composition*
- * Recall what *abstraction* is:
- * Procedural Abstraction: what does the `sqrt()` function do? How does it do it?
- * Object abstraction: the representation of an object is internal to the object and irrelevant to the outside world.
- * The outside world merely interacts with an object by calling its `public` methods
- * Copy constructors: you can define a constructor that takes an object and constructs a new copy of it.
- ```text
- ```
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement