0% found this document useful (0 votes)
37 views

Liang Chapter 9

This document introduces object-oriented programming concepts like classes, objects, and UML class diagrams. It explains that classes define templates for objects with shared behaviors and states, while objects are individual instances of classes. Classes use variables to define data fields and methods to define behaviors. Constructors are special methods used to construct objects from classes.

Uploaded by

Sıla Karadağ
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
37 views

Liang Chapter 9

This document introduces object-oriented programming concepts like classes, objects, and UML class diagrams. It explains that classes define templates for objects with shared behaviors and states, while objects are individual instances of classes. Classes use variables to define data fields and methods to define behaviors. Constructors are special methods used to construct objects from classes.

Uploaded by

Sıla Karadağ
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 11

Motivations

Chapter 9 Objects and Classes After learning the preceding chapters, you are capable of
solving many programming problems using selections,
loops, methods, and arrays. However, these Java features
are not sufficient for developing graphical user interfaces
and large scale software systems. Suppose you want to
develop a graphical user interface as shown below. How do
CS1: Java Programming you program it?
Colorado State University

Original slides by Daniel Liang


Modified slides by Chris Wilcox

Liang, Introduction to Java Programming, Tenth Edition, (c) 2015 Pearson Education, Inc. All Liang, Introduction to Java Programming, Tenth Edition, (c) 2015 Pearson Education, Inc. All
1 2
rights reserved. rights reserved.

Objectives OO Programming Concepts


q To describe objects and classes, and use classes to model objects (§9.2).
q To use UML graphical notation to describe classes and objects (§9.2). Object-oriented programming (OOP) involves
To demonstrate how to define classes and create objects (§9.3).
programming using objects. An object represents
q
q To create objects using constructors (§9.4).
q

q
To access objects via object reference variables (§9.5).
To define a reference variable using a reference type (§9.5.1).
an entity in the real world that can be distinctly
q To access an object’s data and methods using the object member access operator (.) (§9.5.2). identified. For example, a student, a desk, a circle,
q To define data fields of reference types and assign default values for an object’s data fields (§9.5.3).
q To distinguish between object reference variables and primitive data type variables (§9.5.4). a button, and even a loan can all be viewed as
q
q
To use the Java library classes Date, Random, and Point2D (§9.6).
To distinguish between instance and static variables and methods (§9.7).
objects. An object has a unique identity, state, and
q To define private data fields with appropriate get and set methods (§9.8). behaviors. The state of an object consists of a set of
q To encapsulate data fields to make classes easy to maintain (§9.9).
q To develop methods with object arguments and differentiate between primitive-type arguments and data fields (also known as properties) with their
q
object-type arguments (§9.10).
To store and process objects in arrays (§9.11).
current values. The behavior of an object is defined
q To create immutable objects from immutable classes to protect the contents of objects (§9.12). by a set of methods.
q To determine the scope of variables in the context of a class (§9.13).
q To use the keyword this to refer to the calling object itself (§9.14).
Liang, Introduction to Java Programming, Tenth Edition, (c) 2015 Pearson Education, Inc. All Liang, Introduction to Java Programming, Tenth Edition, (c) 2015 Pearson Education, Inc. All
3 4
rights reserved. rights reserved.

Objects Classes
Class Name: Circle A class template

Data Fields:
radius is _______
Classes are constructs that define objects of the
Methods:
getArea
same type. A Java class uses variables to define
data fields and methods to define behaviors.
Circle Object 1 Circle Object 2 Circle Object 3 Three objects of
the Circle class
Additionally, a class provides a special type of
Data Fields:
radius is 10
Data Fields:
radius is 25
Data Fields:
radius is 125 methods, known as constructors, which are invoked
to construct objects from the class.
An object has both a state and behavior. The state
defines the object, and the behavior defines what
the object does.

Liang, Introduction to Java Programming, Tenth Edition, (c) 2015 Pearson Education, Inc. All Liang, Introduction to Java Programming, Tenth Edition, (c) 2015 Pearson Education, Inc. All
5 6
rights reserved. rights reserved.
Classes UML Class Diagram
class Circle { Class name
UML Class Diagram Circle
/** The radius of this circle */
double radius = 1.0; radius: double Data fields
Data field
Circle() Constructors and
/** Construct a circle object */ Circle(newRadius: double) methods
Circle() { getArea(): double
} getPerimeter(): double
Constructors setRadius(newRadius:
double): void
/** Construct a circle object */
Circle(double newRadius) {
radius = newRadius;
} circle2: Circle circle3: Circle UML notation
circle1: Circle
for objects
radius = 1.0 radius = 25 radius = 125
/** Return the area of this circle */
double getArea() { Method
return radius * radius * 3.14159;
}
}
Liang, Introduction to Java Programming, Tenth Edition, (c) 2015 Pearson Education, Inc. All Liang, Introduction to Java Programming, Tenth Edition, (c) 2015 Pearson Education, Inc. All
7 8
rights reserved. rights reserved.

Example: Defining Classes and Creating Objects


Example: Defining Classes and
Creating Objects
TV
channel: int The current channel (1 to 120) of this TV.
volumeLevel: int The current volume level (1 to 7) of this TV.
on: boolean Indicates whether this TV is on/off.

Objective: Demonstrate creating objects, The + sign indicates


a public modifier.
+TV()
+turnOn(): void
Constructs a default TV object.
Turns on this TV.

accessing data, and using methods. +turnOff(): void


+setChannel(newChannel: int): void
Turns off this TV.
Sets a new channel for this TV.
+setVolume(newVolumeLevel: int): void Sets a new volume level for this TV.
+channelUp(): void Increas es th e channel number by 1.
+channelDown(): void Decreases the channel n umber by 1.
+volumeUp(): void Increas es th e volume level by 1.
TestSimpleCircle Run +volumeDown(): void Decreases the volume level by 1.

TV

TestTV Run

Liang, Introduction to Java Programming, Tenth Edition, (c) 2015 Pearson Education, Inc. All Liang, Introduction to Java Programming, Tenth Edition, (c) 2015 Pearson Education, Inc. All
9 10
rights reserved. rights reserved.

Constructors Constructors, cont.


Constructors are a special A constructor with no parameters is referred to as a
Circle() { kind of methods that are no-arg constructor.
} invoked to construct objects.
· Constructors must have the same name as the
Circle(double newRadius) { class itself.
radius = newRadius; · Constructors do not have a return type—not
} even void.
· Constructors are invoked using the new
operator when an object is created. Constructors
play the role of initializing objects.
Liang, Introduction to Java Programming, Tenth Edition, (c) 2015 Pearson Education, Inc. All Liang, Introduction to Java Programming, Tenth Edition, (c) 2015 Pearson Education, Inc. All
11 12
rights reserved. rights reserved.
Creating Objects Using Default Constructor
Constructors
A class may be defined without constructors. In
new ClassName();
this case, a no-arg constructor with an empty body
is implicitly defined in the class. This constructor,
Example: called a default constructor, is provided
new Circle(); automatically only if no constructors are explicitly
defined in the class.
new Circle(5.0);

Liang, Introduction to Java Programming, Tenth Edition, (c) 2015 Pearson Education, Inc. All Liang, Introduction to Java Programming, Tenth Edition, (c) 2015 Pearson Education, Inc. All
13 14
rights reserved. rights reserved.

Declaring Object Reference Variables Declaring/Creating Objects


To reference an object, assign the object to a reference in a Single Step
variable.
ClassName objectRefVar = new ClassName();
To declare a reference variable, use the syntax: Assign object reference Create an object
Example:
ClassName objectRefVar; Circle myCircle = new Circle();

Example:
Circle myCircle;

Liang, Introduction to Java Programming, Tenth Edition, (c) 2015 Pearson Education, Inc. All Liang, Introduction to Java Programming, Tenth Edition, (c) 2015 Pearson Education, Inc. All
15 16
rights reserved. rights reserved.

animation

Accessing Object’s Members Trace Code


Declare myCircle
q Referencing the object’s data:
objectRefVar.data Circle myCircle = new Circle(5.0); myCircle no value
e.g., myCircle.radius Circle yourCircle = new Circle();

yourCircle.radius = 100;

q Invoking the object’s method:


objectRefVar.methodName(arguments)
e.g., myCircle.getArea()

Liang, Introduction to Java Programming, Tenth Edition, (c) 2015 Pearson Education, Inc. All Liang, Introduction to Java Programming, Tenth Edition, (c) 2015 Pearson Education, Inc. All
17 18
rights reserved. rights reserved.
animation animation
Trace Code, cont. Trace Code, cont.

Circle myCircle = new Circle(5.0); myCircle no value Circle myCircle = new Circle(5.0); myCircle reference value
Circle yourCircle = new Circle(); Circle yourCircle = new Circle();

yourCircle.radius = 100; : Circle yourCircle.radius = 100; Assign object reference : Circle


to myCircle
radius: 5.0 radius: 5.0

Create a circle

Liang, Introduction to Java Programming, Tenth Edition, (c) 2015 Pearson Education, Inc. All Liang, Introduction to Java Programming, Tenth Edition, (c) 2015 Pearson Education, Inc. All
19 20
rights reserved. rights reserved.

animation animation
Trace Code, cont. Trace Code, cont.
Circle myCircle = new Circle(5.0); myCircle reference value Circle myCircle = new Circle(5.0); myCircle reference value
Circle yourCircle = new Circle(); Circle yourCircle = new Circle();

yourCircle.radius = 100; : Circle yourCircle.radius = 100; : Circle

radius: 5.0 radius: 5.0

yourCircle no value yourCircle no value

: Circle
Declare yourCircle Create a new radius: 1.0
Circle object

Liang, Introduction to Java Programming, Tenth Edition, (c) 2015 Pearson Education, Inc. All Liang, Introduction to Java Programming, Tenth Edition, (c) 2015 Pearson Education, Inc. All
21 22
rights reserved. rights reserved.

animation animation
Trace Code, cont. Trace Code, cont.
Circle myCircle = new Circle(5.0); myCircle reference value Circle myCircle = new Circle(5.0); myCircle reference value
Circle yourCircle = new Circle(); Circle yourCircle = new Circle();

yourCircle.radius = 100; : Circle yourCircle.radius = 100; : Circle

radius: 5.0 radius: 5.0

yourCircle reference value yourCircle reference value

Assign object reference


to yourCircle : Circle : Circle

radius: 1.0
Change radius in radius: 100.0
yourCircle

Liang, Introduction to Java Programming, Tenth Edition, (c) 2015 Pearson Education, Inc. All Liang, Introduction to Java Programming, Tenth Edition, (c) 2015 Pearson Education, Inc. All
23 24
rights reserved. rights reserved.
Caution Reference Data Fields
Recall that you use The data fields can be of reference types. For example,
Math.methodName(arguments) (e.g., Math.pow(3, 2.5)) the following Student class contains a data field name of
the String type.
to invoke a method in the Math class. Can you invoke getArea() using
SimpleCircle.getArea()? The answer is no. All the methods used before public class Student {
String name; // name has default value null
this chapter are static methods, which are defined using the static int age; // age has default value 0
keyword. However, getArea() is non-static. It must be invoked from an boolean isScienceMajor; // isScienceMajor has default value false
object using char gender; // c has default value '\u0000'
}

objectRefVar.methodName(arguments) (e.g., myCircle.getArea()).

More explanations will be given in the section on “Static Variables,


Constants, and Methods.”

Liang, Introduction to Java Programming, Tenth Edition, (c) 2015 Pearson Education, Inc. All Liang, Introduction to Java Programming, Tenth Edition, (c) 2015 Pearson Education, Inc. All
25 26
rights reserved. rights reserved.

The null Value Default Value for a Data Field


If a data field of a reference type does not The default value of a data field is null for a
reference type, 0 for a numeric type, false for a
reference any object, the data field holds a boolean type, and '\u0000' for a char type.
special literal value, null. However, Java assigns no default value to a local
variable inside a method.
public class Test {
public static void main(String[] args) {
Student student = new Student();
System.out.println("name? " + student.name);
System.out.println("age? " + student.age);
System.out.println("isScienceMajor? " + student.isScienceMajor);
System.out.println("gender? " + student.gender);
}
}

Liang, Introduction to Java Programming, Tenth Edition, (c) 2015 Pearson Education, Inc. All Liang, Introduction to Java Programming, Tenth Edition, (c) 2015 Pearson Education, Inc. All
27 28
rights reserved. rights reserved.

Differences between Variables of


Example Primitive Data Types and Object Types
Java assigns no default value to a local variable
inside a method. Created using new Circle()
Primitive type int i = 1 i 1
public class Test {
public static void main(String[] args) { Object type Circle c c reference c: Circle
int x; // x has no default value
String y; // y has no default value radius = 1
System.out.println("x is " + x);
System.out.println("y is " + y);
}
}

Compile error: variable not


initialized
Liang, Introduction to Java Programming, Tenth Edition, (c) 2015 Pearson Education, Inc. All Liang, Introduction to Java Programming, Tenth Edition, (c) 2015 Pearson Education, Inc. All
29 30
rights reserved. rights reserved.
Copying Variables of Primitive
Garbage Collection
Data Types and Object Types
Primitive type assignment i = j
As shown in the previous figure, after the
Before: After: assignment statement c1 = c2, c1 points to
i 1 i 2 the same object referenced by c2. The object
j 2 j 2 previously referenced by c1 is no longer
Before:
Object type assignment c1 = c2
referenced. This object is known as garbage.
After:

c1 c1
Garbage is automatically collected by JVM.
c2 c2

c1: Circle c2: Circle c1: Circle c2: Circle


radius = 5 radius = 9 radius = 5 radius = 9

Liang, Introduction to Java Programming, Tenth Edition, (c) 2015 Pearson Education, Inc. All Liang, Introduction to Java Programming, Tenth Edition, (c) 2015 Pearson Education, Inc. All
31 32
rights reserved. rights reserved.

Garbage Collection, cont The Date Class


Java provides a system-independent encapsulation of date
TIP: If you know that an object is no longer and time in the java.util.Date class. You can use the Date
class to create an instance for the current date and time and
needed, you can explicitly assign null to a use its toString method to return the date and time as a string.
reference variable for the object. The JVM
will automatically collect the space if the The + sign indicates
public modifer +Date()
java.util.Date

Constructs a Date object for the current time.


object is not referenced by any variable. +Date(elapseTime: long) Constructs a Date object for a given time in
milliseconds elapsed since January 1, 1970, GMT.
+toString(): String Returns a string representing the date and time.
+getTime(): long Returns the number of milliseconds since January 1,
1970, GMT.
+setTime(elapseTime: long): void Sets a new elapse time in the object.

Liang, Introduction to Java Programming, Tenth Edition, (c) 2015 Pearson Education, Inc. All Liang, Introduction to Java Programming, Tenth Edition, (c) 2015 Pearson Education, Inc. All
33 34
rights reserved. rights reserved.

The Date Class Example The Random Class


For example, the following code You have used Math.random() to obtain a random double
value between 0.0 and 1.0 (excluding 1.0). A more useful
random number generator is provided in the java.util.Random
java.util.Date date = new java.util.Date(); class.
System.out.println(date.toString());
java.util.Random
+Random() Constructs a Random object with the current time as its seed.
displays a string like Sun Mar 09 13:50:19 +Random(seed: long) Constructs a Random object with a specified seed.
+nextInt(): int Returns a random int value.
EST 2003. +nextInt(n: int): int Returns a random int value between 0 and n (exclusive).
+nextLong(): long Returns a random long value.
+nextDouble(): double Returns a random double value between 0.0 and 1.0 (exclusive).
+nextFloat(): float Returns a random float value between 0.0F and 1.0F (exclusive).
+nextBoolean(): boolean Returns a random boolean value.

Liang, Introduction to Java Programming, Tenth Edition, (c) 2015 Pearson Education, Inc. All Liang, Introduction to Java Programming, Tenth Edition, (c) 2015 Pearson Education, Inc. All
35 36
rights reserved. rights reserved.
The Random Class Example The Point2D Class
If two Random objects have the same seed, they will generate Java API has a conveninent Point2D class in the
identical sequences of numbers. For example, the following javafx.geometry package for representing a point in a two-
code creates two Random objects with the same seed 3. dimensional plane.
Random random1 = new Random(3);
System.out.print("From random1: ");
for (int i = 0; i < 10; i++)
System.out.print(random1.nextInt(1000) + " ");
Random random2 = new Random(3);
System.out.print("\nFrom random2: ");
for (int i = 0; i < 10; i++)
System.out.print(random2.nextInt(1000) + " ");
TestPoint2D Run
From random1: 734 660 210 581 128 202 549 564 459 961
From random2: 734 660 210 581 128 202 549 564 459 961

Liang, Introduction to Java Programming, Tenth Edition, (c) 2015 Pearson Education, Inc. All Liang, Introduction to Java Programming, Tenth Edition, (c) 2015 Pearson Education, Inc. All
37 38
rights reserved. rights reserved.

Instance Static Variables, Constants,


Variables, and Methods and Methods
Static variables are shared by all the instances of the
Instance variables belong to a specific instance. class.

Instance methods are invoked by an instance of Static methods are not tied to a specific object.
the class.
Static constants are final variables shared by all the
Instance variables and methods are specified by instances of the class.
omitting the static keyword.

Liang, Introduction to Java Programming, Tenth Edition, (c) 2015 Pearson Education, Inc. All Liang, Introduction to Java Programming, Tenth Edition, (c) 2015 Pearson Education, Inc. All
39 40
rights reserved. rights reserved.

Static Variables, Constants, Static Variables, Constants,


and Methods, cont. and Methods, cont.

To declare static variables, constants, and methods,


use the static modifier.

Liang, Introduction to Java Programming, Tenth Edition, (c) 2015 Pearson Education, Inc. All Liang, Introduction to Java Programming, Tenth Edition, (c) 2015 Pearson Education, Inc. All
41 42
rights reserved. rights reserved.
Example of Visibility Modifiers and
Using Instance and Class Variables Accessor/Mutator Methods
and Method By default, the class, variable, or method can be
accessed by any class in the same package.
Objective: Demonstrate the roles of
q public
instance and class variables and their
The class, data, or method is visible to any class in any
uses. This example adds a class variable package.
numberOfObjects to track the number of
Circle objects created. q private
The data or methods can be accessed only by the declaring
CircleWithStaticMembers class.
TestCircleWithStaticMembers Run The get and set methods are used to read and modify private
properties.
Liang, Introduction to Java Programming, Tenth Edition, (c) 2015 Pearson Education, Inc. All Liang, Introduction to Java Programming, Tenth Edition, (c) 2015 Pearson Education, Inc. All
43 44
rights reserved. rights reserved.

The default modifier on a class restricts access to within a package,


The private modifier restricts access to within a class, the default and the public modifier enables unrestricted access.
modifier restricts access to within a package, and the public
modifier enables unrestricted access.

Liang, Introduction to Java Programming, Tenth Edition, (c) 2015 Pearson Education, Inc. All Liang, Introduction to Java Programming, Tenth Edition, (c) 2015 Pearson Education, Inc. All
45 46
rights reserved. rights reserved.

NOTE Why Data Fields Should Be


private?
An object cannot access its private members, as shown in (b).
It is OK, however, if the object is declared in its own class, as To protect data.
shown in (a).
To make code easy to maintain.

Liang, Introduction to Java Programming, Tenth Edition, (c) 2015 Pearson Education, Inc. All Liang, Introduction to Java Programming, Tenth Edition, (c) 2015 Pearson Education, Inc. All
47 48
rights reserved. rights reserved.
Example of Passing Objects to Methods
Data Field Encapsulation
Circle
q Passing by value for primitive type value
The - sign indicates
private modifier -radius: double The radius of this circle (default: 1.0). (the value is passed to the parameter)
-numberOfObjects: int The number of circle objects created.

+Circle() Constructs a default circle object. q Passing by value for reference type value
+Circle(radius: double)
+getRadius(): double
Constructs a circle object with the specified radius.
Returns the radius of this circle.
(the value is the reference to the object)
+setRadius(radius: double): void Sets a new radius for this circle.
+getNumberOfObjects(): int Returns the number of circle objects created.
+getArea(): double Returns the area of this circle.

CircleWithPrivateDataFields
TestPassObject Run
TestCircleWithPrivateDataFields Run
Liang, Introduction to Java Programming, Tenth Edition, (c) 2015 Pearson Education, Inc. All Liang, Introduction to Java Programming, Tenth Edition, (c) 2015 Pearson Education, Inc. All
49 50
rights reserved. rights reserved.

Passing Objects to Methods, cont.


Array of Objects
Circle[] circleArray = new Circle[10];

An array of objects is actually an array of


reference variables. So invoking
circleArray[1].getArea() involves two
levels of referencing as shown in the next
figure. circleArray references to the entire
array. circleArray[1] references to a
Circle object.
Liang, Introduction to Java Programming, Tenth Edition, (c) 2015 Pearson Education, Inc. All Liang, Introduction to Java Programming, Tenth Edition, (c) 2015 Pearson Education, Inc. All
51 52
rights reserved. rights reserved.

Array of Objects, cont. Array of Objects, cont.


Circle[] circleArray = new Circle[10]; Summarizing the areas of the circles

TotalArea Run

Liang, Introduction to Java Programming, Tenth Edition, (c) 2015 Pearson Education, Inc. All Liang, Introduction to Java Programming, Tenth Edition, (c) 2015 Pearson Education, Inc. All
53 54
rights reserved. rights reserved.
Immutable Objects and Classes Example public class BirthDate {
private int year;
public class Student {
private int id;
private int month;
If the contents of an object cannot be changed once the object private BirthDate birthDate;
private int day;

is created, the object is called an immutable object and its class public Student(int ssn,
int year, int month, int day) {
public BirthDate(int newYear,
int newMonth, int newDay) {
is called an immutable class. If you delete the set method in id = ssn;
birthDate = new BirthDate(year, month, day);
year = newYear;
} month = newMonth;
the Circle class in Listing 8.10, the class would be immutable day = newDay;
public int getId() {
because radius is private and cannot be changed without a set return id;
}
}
method. public void setYear(int newYear) {
public BirthDate getBirthDate() { year = newYear;
return birthDate;
}
}
A class with all private data fields and without mutators is not }
}

necessarily immutable. For example, the following class


public class Test {
Student has all private data fields and no mutators, but it is public static void main(String[] args) {
mutable. Student student = new Student(111223333, 1970, 5, 3);
BirthDate date = student.getBirthDate();
date.setYear(2010); // Now the student birth year is changed!
}
}

Liang, Introduction to Java Programming, Tenth Edition, (c) 2015 Pearson Education, Inc. All Liang, Introduction to Java Programming, Tenth Edition, (c) 2015 Pearson Education, Inc. All
55 56
rights reserved. rights reserved.

What Class is Immutable?


Scope of Variables
For a class to be immutable, it must mark all data fields private
and provide no mutator methods and no accessor methods that q The scope of instance and static variables is the
would return a reference to a mutable data field object. entire class. They can be declared anywhere inside
a class.
q The scope of a local variable starts from its
declaration and continues to the end of the block
that contains the variable. A local variable must be
initialized explicitly before it can be used.

Liang, Introduction to Java Programming, Tenth Edition, (c) 2015 Pearson Education, Inc. All Liang, Introduction to Java Programming, Tenth Edition, (c) 2015 Pearson Education, Inc. All
57 58
rights reserved. rights reserved.

The this Keyword Reference the Hidden Data Fields


q The this keyword is the name of a reference that public class F { Suppose that f1 and f2 are two objects of F.
private int i = 5; F f1 = new F(); F f2 = new F();
refers to an object itself. One common use of the private static double k = 0;
Invoking f1.setI(10) is to execute
void setI(int i) { this.i = 10, where this refers f1
this keyword is reference a class’s hidden data }
this.i = i;
Invoking f2.setI(45) is to execute
this.i = 45, where this refers f2
fields. static void setK(double k) {
F.k = k;
}

q Another common use of the this keyword to }

enable a constructor to invoke another


constructor of the same class.

Liang, Introduction to Java Programming, Tenth Edition, (c) 2015 Pearson Education, Inc. All Liang, Introduction to Java Programming, Tenth Edition, (c) 2015 Pearson Education, Inc. All
59 60
rights reserved. rights reserved.
Calling Overloaded Constructor
public class Circle {
private double radius;

public Circle(double radius) {


this.radius = radius;
} this must be explicitly used to reference the data
field radius of the obje ct being constructed
public Circle() {
this(1.0);
} this is used to invoke another constructor

public double getArea() {


return this.radius * this.radius * Math.PI;
}
} Every instance variable be longs to an instance represented by this,
which is normally omitted
Liang, Introduction to Java Programming, Tenth Edition, (c) 2015 Pearson Education, Inc. All
61
rights reserved.

You might also like