Advanced Programming
SUT • Spring 2019
Package
Package access
Static
this
Method overloading
toString
equals
public
Interface access
private
Don’t touch!
public class Person {
public String name;
private Integer age;
public String getName() {
return this.name;
}
private Integer age() {
return this.age;
}
}
public class Main {
public static void main(String[] args) {
Person p = new Person();
p.name = "Ali Alavi";
p.age = 12; // Compile Error
}
}
You can declare a class which is not public
The class is visible within the file
There can be only one public class per file
The name of the public class must exactly match the name of the file
including capitalization
It is possible to have a java file with no public class
not typical
Access specifiers are declared for classes
Not for objects
When a member is declared as private
It is not visible in methods outside this class
It is visible by other objects of the same class
public class Access {
private String name;
public Access(String name) {
this.name = name;
}
public void check(Access access){
access.name = name;
}
public static void main(String[] args) {
Access a = new Access("Ali");
Access b = new Access("Taghi");
a.check(b);
System.out.println(a.name);
System.out.println(b.name);
}
}
a can touch private property (name) of b
Because a and b has the same class
name is not private for b
name is private for Access
A package contains a group of classes
Organized together under a single namespace
Packages organize classes belonging to the same category or providing similar functionality
A package provides a unique namespace for the types it contains
Classes in one package has the same folder
Packages may contain other packages
Hierarchy of packages
java.util
java.lang
java.io
Remember public and private access specifiers
The default access has no keyword
It is commonly referred to as package access
friendly
Other classes in the current package have access to that member
To classes outside of this package, the member appears to be private
import keyword
Class Qualified Name = package-name + class-name
For example
java .lang.String
java.lang.Math
double sqrt = Math.sqrt(123);
java.util.Scanner
java.awt.Event
org.w3c.dom.events.Event
import java.util.Arrays;
import java.util.*;
public class Swapping {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int nextInt = scanner.nextInt();
System.out.println(nextInt);
int[] original = new int[5];
int[] copy = Arrays.copyOf(original, 10);
}
}
public class Swapping {
public static void main(String[] args) {
Integer a = 5;
java.lang.Integer b = 5;
java.lang.String s = "asd";
java.lang.Boolean bb = true;
}
}
java.lang is implicitly imported
Unused imports have a trivial impact on the compiler
But there are no imports in the byte code or at runtime
Unused import have no impact in runtime
But it is better to remove them
Organize Imports
class Peykan{...}
public class Pride {
int color;
int price;
boolean isHatchBack;
int designYear;
int length, width;
}
Properties of objects
Properties of class
When you create a class
You describe how objects of that class look
And how they will behave
You don’t actually get an object until you create one
using new
At that point storage is allocated and methods become available.
There are two situations in which this approach is not sufficient.
Class data or static property
Class method or static method
You want to have only a single piece of storage for a particular field
regardless of how many objects of that class are created
or even if no objects are created
Example:
Pride.designYear
Person.?
Class data = static properties
if you need a method that isn’t associated with any particular object of this class.
You need a method that you can call even if no objects are created
Class methods = static methods
static properties are shared among all the objects
static properties are properties of classes
Not objects
Example:
Integer.MAX_VALUE
Player.NumberOfObjects
public class Person {
private String name;
private int age;
public static int MAX_AGE = 150;
public void setAge(int age) {
if (age < MAX_AGE)
this.age = age;
}
public static int getMaxAge() {
return MAX_AGE;
//no access to age and name
}
}
Static properties are class data, not object data
Constructors are created for initializing object data
How to initialize class data?
Two ways:
Inline values
Static block
Static initialization is done when Class Loader loads the class
public static int MAX_AGE = 150;
private static double PI = 3.14;
static String defaultName = theDefaultName();
private static String theDefaultName() {
return "Ali Alavi";
}
public class Person {
public static int MAX_AGE;
private static double PI;
static String defaultName;
private static String theDefaultName() {
return "Ali Alavi";
}
static {
MAX_AGE = 150;
PI = 3.14;
String s = theDefaultName();
if (s != null)
defaultName = theDefaultName();
}
}
public class SomeClass {
private int value = 0;
{
System.out.println("initialization block: value = " + value + ".");
value = 1;
}
public SomeClass(){
System.out.println("SomeClass(): value = " + value + ".");
value = 2;
}
public SomeClass(int param){
System.out.println("SomeClass(int param): value = " + value + ".");
value = 3;
}
public static void main(String[] args){
SomeClass c1 = new SomeClass();
SomeClass c2 = new SomeClass(2);
}
}
Once per class
Static variable declaration
Static block
Once per object
variable declaration
Initialization block
Constructor
public class Person {
public static int MAX_AGE;
private static double PI = 3.14;
static {
MAX_AGE = 150;
}
private String nation = "Iran";
private int age;
private String name;
{
name = "Ali";
}
public Person() {
age = 10;
}
public Person(int a, String n) {
age = a;
name = n;
}
}
public static void main(String[] args) {
Person p1 = new Person();
Person p2 = new Person(20, "Taghi");
}
How does getArea() know where radius is?
public class Circle {
private double radius;
public Circle(double r) {
this.radius = r;
}
public double getArea() {
return this.radius * this.radius * 3.14;
}
public static void main(String[] args){
Circle c = new Circle(2);
System.out.println(c.getArea());
}
}
A reference to the object is implicitly passed to methods
circle.getArea()
is converted (by compiler) to something like:
Circle.getArea(circle)
What if you want to access this circle object?
Use this keyword
this is available within non-static methods
public class Lead {
int i = 0;
Leaf increment() {
i++;
return this;
}
void print(){
System.out.println("i = " + i);
}
public static void main(String[] args){
Leaf x = new Leaf();
x.increment().increment().increment().print();
}
}
public class Book {
private String name;
private Person author;
public void setName(String name) {
this.name = name;
}
public void setAuthor(Person author) {
this.author = author;
}
}
What are static methods?
Methods without implicit this
Static methods are bound to classes, not objects
Methods with the same name in the same class
With different parameters
Different Signatures
class Circle {
void f() {
System.out.println("f is called");
}
void f(int number) {
System.out.println("f is called with number = " + number);
}
void f(String s) {
System.out.println("f is called with s = " + s);
}
void f(String s, int number) {
System.out.println("f is called with s = " + s +
" and number = " + number);
}
public static void main(String[] args){
Circle circle = new Circle();
circle.f();
circle.f(5);
circle.f("salam");
circle.f("salam", 5);
}
}
Why this is not permitted?
class Circle {
void f() {
System.out.println("f is called");
}
int f() {
System.out.println("f is called");
return 0;
}
}
long longValue = 98127391827L;
int iad = longValue; // Compiler Error
int i = (int) longValue;
Integer intValue = 391827;
Long lad = (Long) intValue; // Runtime Error
Sometimes we want to convert an object to another type
Type casting is not the solution here
We should write some methods to convert the types
Scanner scanner = new Scanner(System.in);
String s = scanner.next();
int intValue = Integer.parseInt(s);
Integer i = 12;
String str = i.toString();
toString() is a special method
You can write it for every class
public class Rectangle {
private int length, width;
public Rectangle(int length, int width) {
this.length = length;
this.width = width;
}
public String toString() {
return "Retangle[length=" + length + ", width=" + width + "]";
}
public int getArea(){
return width + length;
}
public static void main(String[] args){
Rectangle r = new Rectangle(10, 2);
System.out.println(r.getArea());
System.out.println(r.toString());
System.out.println("Here: " + r.toString());
}
}
int i = 5;
int j = 4+1;
System.out.println("i is equal to j: " + (i == j))
String i = new String("ali");
String j = new String("ali");
System.out.println("i is equal to j: " + (i == j))
String i = "ali";
String j = "ali";
System.out.println("i is equal to j: " + (i == j))
String i = new String("ali");
String j = new String("ali");
System.out.println("i is equal to j: " + (i.equals(j)))
public class Person {
private String nationalID;
private String name;
private String email;
private int age;
public boolean equals(Person other) {
return nationalID.equals(other.nationalID);
}
}
Person p1 = new Person("1290786547", "Ali Alavi");
Person p2 = new Person("1290786547", "Taghi Taghavi");
Person p3 = new Person("0578905672", "Taghi Taghavi");
System.out.println(p1.equals(p2));
System.out.println(p2.equals(p3));
In fact, equals() is more complicated
The parameter should be an Object
Person as the parameter was incorrect
More checks are required
IDE Support for writing equals
Use your IDE for
getters, setters, constructors, …
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (nationalID == null) {
if (other.nationalID != null)
return false;
} else if (!nationalID.equals(other.nationalID))
return false;
return true;
}