Java Unit 2

Download as pdf or txt
Download as pdf or txt
You are on page 1of 26

**Java Programming**

UNIT-I

** Java Introduction

Java is a class-based object-oriented simple programming language. Though we can’t


consider it to be fully object-oriented as it supports primitive data types. It is a general -purpose,
high-level programming language that helps programmers and developers to write a code once
and run it anywhere.

Java is also called a platform-independent programming language. Java is a


programming language created by James Gosling from Sun Microsystems (Sun) in 1991. The
first version of java (JDK.1.0) was released on the year 23 January 1996.

Categorized a java applications and it is used?

According to Sun, 3 billion devices run Java. There are many devices where Java is currently
used. Some of them are as follows:

1. Desktop Applications such as acrobat reader, media player, antivirus, etc.


2. Web Applications such as irctc.co.in, javatpoint.com, etc.
3. Enterprise Applications such as banking applications.
4. Mobile
5. Embedded System
6. Smart Card
7. Robotics
8. Games, etc.

Types of Java Applications


There are mainly 4 types of applications that can be created using Java programming:

1) Standalone Application
Standalone applications are also known as desktop applications or window-based
applications. These are traditional software that we need to install on every machine. Examples
of standalone application are Media player, antivirus, etc. AWT and Swing are used in Java for
creating standalone applications.
2) Web Application
An application that runs on the server side and creates a dynamic page is called a web
application. Currently, Servlet, JSP, Struts, Spring, Hibernate, JSF, etc. technologies are used
for creating web applications in Java.

3) Enterprise Application
An application that is distributed in nature, such as banking applications, etc. is called an
enterprise application. It has advantages like high-level security, load balancing, and clustering.
In Java, EJB is used for creating enterprise applications.

4) Mobile Application

An application which is created for mobile devices is called a mobile application. Currently,
Android and Java ME are used for creating mobile applications.

Syntax-
class class_name

public static void main(String [] args)

System.out.print(“ Jai Hind”)

print - Main function args - anything name

void - function return type system - predefine class

string - argument( predefine data type) out - user output print

main - function name print - predefine method

Java Comments-: I. Single Line (//)

II. Multi Line (/*______*/)


** OOPS in Java
Oops stand for object oriented programming language, the main purpose of oops is to
deal with real world entity using programming language. object oriented programming
language is a programming concept that works on the principles of abstraction, encapsulation,
inheritance, and polymorphism. It allows users to create objects they want and create methods
to handle those objects. The basic concept of OOPs is to create objects, re-use them
throughout the program, and manipulate these objects to get results.

** Features of OOPS

Class:- A class can be defined as a template/blueprint that describes the behavior/state that
the object of its type support.

Object:- Objects have states and behaviors. (Collection of object is a class) Example: A dog
has states - color, name, breed as well as behaviors – wagging the tail, barking, eating. An
object is an instance of a class.

Inheritance:- Inheritance means creating new classes based on existing ones. A class that
inherits from another class can reuse the methods and fields of that class. In addition, you can
add new fields and methods to your current class as well.

Polymorphism:- Polymorphism is considered one of the important features of Object-Oriented


Programming. Polymorphism allows us to perform a single action in different ways. In other
words, polymorphism allows you to define one interface and have multiple implementations. The
word “poly” means many and “morphs” means forms, so it means many forms.
Abstraction:-Abstraction is the property by virtue of which only the essential details are
displayed to the user. The trivial or the non-essential units are not displayed to the user. Ex: A
car is viewed as a car rather than its individual components.

Encapsulation:- Encapsulation is a fundamental concept in object-oriented programming


(OOP) that refers to the bundling of data and methods that operate on that data within a single
unit, which is called a class in Java. Encapsulation is a way of hiding the implementation details
of a class from outside access and only exposing a public interface that can be used to interact
with the class.

** Features of Java
Simple Object-Oriented Portable Platform independent

Secured Robust Architecture neutral Interpreted

High Performance Multithreaded Distributed Dynamic

Object Oriented:- Java is an Object Oriented Programming Language, which means in Java
everything is written in terms of classes and objects. Now, what is an Object? The object is
nothing but a real-world entity that can represent any person, place, or thing and can be
distinguished from others. Every object near us has some state and behavior associated with it.

Platform independent:- Unlike other programming languages such as C, C++ etc which are
compiled into platform specific machines. Java is guaranteed to be write-once, run-anywhere
language. On compilation Java program is compiled into bytecode. This bytecode is platform
independent and can be run on any machine, plus this bytecode format also provide security.
Any machine with Java Runtime Environment can run Java Programs.

Secure:- When it comes to security, Java is always the first choice. With java secure features it
enable us to develop virus free, temper free system. Java program always runs in Java runtime
environment with almost null interaction with system OS, hence it is more secure.

Multi Threading:- Java multithreading feature makes it possible to write program that can do
many tasks simultaneously. Benefit of multithreading is that it utilizes same memory and other
resources to execute multiple threads at the same time, like While typing, grammatical errors
are checked along.

Architectural Neutral:- Compiler generates bytecodes, which have nothing to do with a


particular computer architecture, hence a Java program is easy to interpreter on any machine.

Portable:- Java Byte code can be carried to any platform. No implementation dependent
features. Everything related to storage is predefined, example: size of primitive data typesHigh
Performance

Java is an interpreted language, so it will never be as fast as a compiled language like C or


C++. But, Java enables high performance with the use of just-in-time compiler.

Distributed:- Java is also a distributed language. Programs can be designed to run on


computer networks. Java has a special class library for communicating using TCP/IP protocols.
Creating network connections is very much easy in Java as compared to C/C++.

Simple:-Java is easy to learn and its syntax is quite simple, clean and easy to understand.The
confusing and ambiguous concepts of C++ are either left out in Java or they have been re-
implemented in a cleaner way.

**Variable

A variable is the name of a reserved area allocated in memory. In other words, it is a


name of the memory location. It is a combination of "vary + able" which means its value can be
changed.

Types of Variables

There are three types of variables in Java:


1) Local Variable

A variable declared inside the body of the method is called local variable. You can use this
variable only within that method and the other methods in the class aren't even aware that the
variable exists. A local variable cannot be defined with "static" keyword.

Syntax:- Void fan(int a){

Int x; //local variable

2) Instance Variable

A variable declared inside the class but outside the body of the method, is called an instance
variable. It is not declared as static. It is called an instance variable because its value is
instance-specific and is not shared among instances.

Syntax:- class A {

Int a;{

Public static void main()}

3) Static variable

A variable that is declared as static is called a static variable. It cannot be local. You can create
a single copy of the static variable and share it among all the instances of the class. Memory
allocation for static variables happens only once when the class is loaded in the memory.

Syntax :- Static int x;

Example :- class A{

Static int b=20; //static


Int c=30; //instance

Public static void main(String [] args)

Int a=10; // local

A r=new A();

System.out.println(a);

System.out.println(A.b);

System.out.println(r.c);

**Data Type
Data types in Java are of different sizes and values that can be stored in the variable that is
made as per convenience and circumstances to cover up all test cases. Java has two
categories in which data types are segregated
1. Primitive Data Type: such as boolean, char, int, short, byte, long, float, and double
2. Non-Primitive Data Type or Object Data type: such as String, Array, etc.

**Fundamental Programming Structure in Java


First Java Program:

class Hello{

Public static void main(String args[]) {


Syastem.out.println(“Hello world”); }

 Class :- class keyword is used to declare in java.


 Public :- It is an access specifier. Public means this function is visible to all.
 Static :- Static is a keyword used to make a fundamental static to execute a static
function. You do not have to create an object of class. The main() method here is called
by JVM, without creating any object for class.
 Void :- It is the return type. Meaning the function with not return anything.
 Main :-main() method is most important method is a java program. This is the method
which is execute, hence all the logic must be inside the main() method. If a java class
not having a main() method. It comes compilation error.

**Abstract Class
An abstract class is a class. That is declared abstract keyword. We can’t create object for
abstract class.( but create a reference variable).

It may or may not include abstract methods. Abstract class can’t be instantiated, but they can be
sub classed. When an abstract class is sub classes. The sub class usually provides
implementations for all of the abstract method in its parent class.

 Abstract class purpose:– main purpose of the abstract class is to create a base
from which many other classes. can be derived.
 Advantages:- an abstract class provides the provider of data hiding in java.
Syntax:- abstract class A
{
-------
-------}

Program:-

abstract class animal{

class demo{

public static void main(String args[]){

animal r= new animal();} //animal is a abstract class not create a object

Note- If the class is normal not abstract, than no one will give error

**Abstract Method
A method which contain abstract modifier at the time of declaration is called abstract method.

Syntax:- class A{

abstract void M1();

 It can only be used in abstract class.


 It doesn’t contain any body {} and always ends with “;”
 Abstract method must be overridden in sub-classes otherwise it will also become a
abstract class.
 Wherever the action is common but implementation are different then we should use
abstract method.

Program:-
public abstract class fruit
{
public abstract void taste();
}
class mango extends fruit
{
public void taste()
{
System.out.println(" Mango is Sweet");
}
}
class orange extends fruit
{
public void taste()
{
System.out.println("Orange is sour");
}
}
class display
{
public static void main(String []args)
{
mango m=new mango();
orange o=new orange();
m.taste(); o.taste();
}
}

Output:- Mango is Sweet

Orange is sour

** Interface
Interface is a just like a class which contains only abstract method. (Collection of
abstract method called interface) to achieve interface java provides a keyword called
implements
 Interface methods are by default public and abstract.
Ex- interface client
{
void M1 (); // (by default public, abstract)
}
 .interface variable are by default public+static+final
 Interface method must be override inside the implementing classes.
 Interface nothing but deals between client and developer.

Input

Client Developer

Output

Interface

Difference between Class and Interface

The major differences between a class and an interface are:

S.
No. Class Interface

In class, you can instantiate variables In an interface, you can’t instantiate


1.
and create an object. variables and create an object.

The interface cannot contain


Class can contain concrete(with
2. concrete(with implementation)
implementation) methods
methods

The access specifiers used with


In Interface only one specifier is
3. classes are private, protected, and
used- Public.
public.
** Methods
Method is a group/block of codes which take input from the user, processed it
and give output. A method of Java is a collection of statements that perform some specific task
and return the result to the caller. A Java method can perform some specific task without
returning anything. Java Methods allow us to reuse the code without retyping the code.

User Input Processed Output

Types of Methods:- Same as C++ two types of methods

Method

Pre-defined User-defined

Print(); sort(); sqrt(); NextInt(); add() sub() M1() shoe()

 Predefined methods are end for semicoulm(;)


print(); :- System class
sort(); :- Array class
squt(); :- math class
NextInt(); :- scanner class
 Why use methods :- 1. Decrees line code (DLC)
 Readability
 Repeatation

Program:-
public class method
{
public static void add()
{
int a=10, b=20;
System.out.print("Sum= "+(a+b));
}
void disp()
{
System.out.println("Add two Numbers");
}
public static void main(String args[])
{
method r=new method();
r.disp();
method.add();
method.add();
method.add();
method.add();
method.add();
}
}
Output: - Add two Numbers

Sum= 30Sum= 30Sum= 30Sum= 30Sum= 30

** Inheritance

When we construct a new class from existing class in such a way that the new class
access all the features and properties of existing class called inheritance.

Note:-

 It java extends keyword used to perform inheritance.


 It provides code reusability.
 We can’t access private member of class through inheritance.
 Method overriding only possible through inheritance.

Syntax:- class A // super class (parent class){

____+, -

class B extends A //Sub class (child class) {

____*,%

Types of Inheritance:-

1. Single Inheritance:- Simple inheritance nothing but which contain only one super
class and one sub class is called simple inheritance.
Syntax :- class super //
{ Super class
___
}
class sub extends super
{ Sub class
___
}
Program:-
class student
{
int roll, marks;
String name;
void input()
{
System.out.println("Enter Roll Name & Marks:");
}
}
class ankit extends student
{
void form()
{
roll=1; name="Ankit"; marks=90;
System.out.println(roll+" "+name+" "+marks);
}
public static void main(String[] args)
{
ankit r=new ankit();
r.input(); r.form();
}
}
Output:-

Enter Roll Name & Marks:

1 Ankit 90

2. Multi-level Inheritance:-In Multi-level inheritance we have only one super class and
multiple sub classes called multi-level inheritance.

Syntax:- class super{

}
super
class sub1 extends super{

} sub1
class sub2 extends sub1

{ sub2

Program:-
public class calculater
{
int a,b,c;
public void add()
{
a=10; b=20;
c=a+b;
System.out.println("Sum of two number:- "+c);
}
public void sub()
{
a=200; b=100;
c=a-b;
System.out.println("Sub of two number:- "+c);
}
}
class B extends calculater
{
public void multi()
{
a=10; b=20;
c=a*b;
System.out.println("Sultiplication of two number:- "+c);
}
public void divi()
{
a=10; b=2;
c=a/b;
System.out.println("Division of two no:- "+c);
}
}
class C extends B
{
public void rem()
{
a=10; b=3;
c=a%b;
System.out.println("Remainder of two number:- "+c);
}
}
class multilevel
{
public static void main(String args[])
{
C r= new C();
r.add();r.sub(); r.multi(); r.divi(); r.rem();
}
}

Output:-
Sum of two number:- 30

sub of two number:- 100

multiplication of two number:- 200

Division of two no:- 5

Remainder of two number:- 1

3. Hierarchical Inheritance:- A Inheritance which only one super class and multiple sub
class and all sub class directly extends super class called hierarchical inheritance.

Syntax:- class A{

}
super
class B extends A {
}

class C extends A{
sub sub sub
}

Program:-
public class inheri
{
void input()
{
System.out.println("Enter your name:- ");
}
}
class B extends inheri
{
void show()
{
System.out.println("My name is Ram");
}
}
class C extends inheri
{
void display()
{
System.out.println("My name is Shyam");
}
}
class Demo
{
public static void main(String args [])
{
B r=new B();
C r2=new C();
r.input(); r.show();
r2.input(); r2.display(); }
}
Output:- Enter your name:-

My name is Ram

Enter your name:-

My name is Shyam

** Overloading
Polymorphism

Compile Time Run Time

Method overloading Method overriding

 Compile Time:- A polymorphism which is exists at the time of compilation is called compile
time early binding or static polymorphism. Ex.
Method overloading: - Whenever a class contains more than one method with
same name and different type of parameters called method overloading.

Syntax: - reture_type_name(parameter);

reture_type method_name(parameter, parameter);

Program:-
class overl
{
void add()
{
int a=10, b=20, c;
c=a+b;
System.out.println(c);
}
void add (int x, int y)
{
int c;
c=x+y;
System.out.println(c);
}
void add(int x, double y)
{
double c;
c=x+y;
System.out.println(c);
}
public static void main(String args [])
{
overl o=new overl();
o.add(); o.add(100,200); o.add(50,45.25);
}
}
Output: - 30

300

95.25

** Overriding

 Run Time: - A polymorphism which exists at the time of execution of program is called
runtime polymorphism. Ex.

Method Overriding: - Whenever we writing method in super and sub classes in such a way
that method name and parameter must be same called method overriding.

Syntax: - class A{ // class


void show(){ //method
} Same
class B extends A{
void show(){ // method
}
}
public class parent
{
void show()
{
System.out.println("Parent's show()");
}
}
class Child extends parent
{
@Override
void show()
{

System.out.println("Child's show()");
}
}
class Main
{
public static void main(String[] args)
{
// parent obj1 = new parent();
// obj1.show();
parent obj = new Child();
obj.show();
}
}

Output: -
Child's show()

**Package in Java

A package arrange numbers of classes interface and sub-package of type into a


particular group. (package is nothing but folder in windows.)

Types of package

Pre-defined User-defined

java.lang java.applit java.net java.IO package P1 package mypack

java.util java.awt java.SQL package add

Pre-defined package: - The package which are already created by java developer peple are
called pre-defined package. Ex- java.lang

 java.lang: - It is the default package also know as heart of the java, because with out using
this package we can’t write a even a single program and we need not to import this
package.
Example: - System, String, Object, Integer, etc (pre-defined class).

 java.util: - This package is used to implement data structure of java (data structure related
pages) it contain utility classes also known as collection frameworks.

Example: - Linklist, stack, vector, hashset, treeset, etc.

 java.IO: - IO stand for input/output this package is very useful to perform input/output
operation on file.

Example: - file. File written, fileReader etc.

 java.applet: - This package mainly use to develop GUI related application. Applet program
are web related program. Created at server but executed at client machine.

Example: - applet.

 java.awt:- awt stand for abstract window tool kit. It is also used to developed GUI
application. The only different between applet & awt program is awt program are stand
alone program & it contain main() unlike applet.

Example: - Frame, Buttom, taxtfile, etc.

 java.Net: - URL, Inet Address, URL connection and so on.


 Java.SQL: - Connection, statement, Resultset etc.

Advantage of Java Package: -

1. Java package is used to categorize the classes and interfaces so that they can be easily
maintained.
2. Java package provides access protection.
3. Java package removes naming collision.
4. Reusability.
5. Security.
6. Fast Searching.
7. Hiding

Dis-advantage of Java Package: -

We can’t pass parameter to package

Ex- P1(____) P2

A A

Program: -
import java.System;
import java.lang.String;

import java.util.Scanner;

class MyClass {
public static void main(String[] args)
{
Scanner Obj = new Scanner(System.in);
System.out.println("Enter username");

String userName = Obj.nextLine();


System.out.println("Username is: " + userName);
}
}

Output:- Enter username

Aaradhya

Username is: Aaradhya

User-defined:- These are the packages that are defined by the user. First we create a
directory myPackage (name should be same as the name of the package). Then create
the MyClass inside the directory with the first statement being the package names.

**Exception
Exception is an unwanted or unexpected event, which occurs during the execution of a
program, i.e. at run time, that disrupts the normal flow of the program’s instructions. Exceptions
can be caught and handled by the program. When an exception occurs within a method, it
creates an object. This object is called the exception object. It contains information about the
exception, such as the name and description of the exception and the state of the program
when the exception occurred.

Exception Handling: -In exception handling, we should have an alternate source


through which we can handle the exception.

Major reasons why an exception Occurs


 Invalid user input
 Device failure
 Loss of network connection
 Physical limitations (out of disk memory)
 Code errors
 Opening an unavailable file
Errors represent irrecoverable conditions such as Java virtual machine (JVM) running out of
memory, memory leaks, stack overflow errors, library incompatibility, infinite recursion, etc.
Errors are usually beyond the control of the programmer, and we should not try to handle errors.
Let us discuss the most important part which is the differences between Error and
Exception that is as follows:
 Error: An Error indicates a serious problem that a reasonable application should not try to
catch.
 Exception: Exception indicates conditions that a reasonable application might try to catch.

Types of Exceptions

Built-in Exceptions:
Built-in exceptions are the exceptions that are available in Java libraries. These exceptions are
suitable to explain certain error situations
.

 Checked Exceptions: - Checked exceptions are called compile-time exceptions because


these exceptions are checked at compile-time by the compiler.

 Unchecked Exceptions: - The unchecked exceptions are just opposite to the checked
exceptions. The compiler will not check these exceptions at compile time. In simple words, if
a program throws an unchecked exception, and even if we didn’t handle or declare it, the
program would not give a compilation error.

User-Defined Exceptions:
Sometimes, the built-in exceptions in Java are not able to describe a certain situation. In such
cases, users can also create exceptions, which are called ‘user-defined Exceptions’.
Advantages of Exception Handling: -
1. Provision to Complete Program Execution
2. Easy Identification of Program Code and Error-Handling Code
3. Propagation of Errors
4. Meaningful Error Reporting
5. Identifying Error Types

The object orientation mechanism has provided the following techniques to work with
exception.
try catch throw throws finally

Pre-defined User-defined

If you have such line of code. Whichever you want whether the exception is there or not but it is
compulsory to execute, then it will be done finally.

Keyword Description

try The "try" keyword is used to specify a block where we should place an exception
code. It means we can't use try block alone. The try block must be followed by
either catch or finally.
catch The "catch" block is used to handle the exception. It must be preceded by try block
which means we can't use catch block alone. It can be followed by finally block
later.
finally The "finally" block is used to execute the necessary code of the program. It is
executed whether an exception is handled or not.
throw The "throw" keyword is used to throw an exception.
throws The "throws" keyword is used to declare exceptions. It specifies that there may
occur an exception in the method. It doesn't throw an exception. It is always used
with method signature.

Program: - try and catch

class Test
{
public static void main(String args[])
{
System.out.println("method is started");
int a=10,b=0,c;
try {
c=a/b ;
System.out.println(c);
}
catch(Exception e)//ArithmeticalException
{
//System.out.println("can't divide by zero");
System.out.println("Can't divided by zero");
}
System.out.println("method is ended");
}
}

Output: -

method is started

Can't divided by zero

method is ended

Program: - Throw

public class throwDemo


{
public static void main(String args[])
{
System.out.println(10/0);
//throw new ArithmeticException("Divide By Zero");
}
}

Program: -Throws

public class throwsDemo


{
public static void main(String args[])//throws InterruptedException
{
for(int i=1;i<=10;i++)
{
System.out.print(i);
Thread.sleep(1000);
}
}
}

Output: - Exception in thread "main" java.lang.Error: Unresolved compilation problem:

Unhandled exception type InterruptedException at throwsDemo.main(throwsDemo.java:9)

Program: -Throws

public class throwsDemo


{
public static void main(String args[])
throws InterruptedException
{
for(int i=1;i<=10;i++)
{
System.out.print(i);
Thread.sleep(1000);
}
}
}

Output: - 12345678910

**Thread
Thread class provide constructors and methods to create and perform operations on a
thread. Thread is a pre-defined class which is available in java.lang package.

Thread is a basic unit of CPU and it is well known for independent execution.

There are two ways to create a thread:

1. By extending Thread class


2. By implementing Runnable interface.

Used methods of Thread class:


1. public void run(): is used to perform action for a thread.
2. public void start(): starts the execution of the thread.JVM calls the run() method on the thread.
3. public void sleep(long miliseconds): Causes the currently executing thread to sleep
(temporarily cease execution) for the specified number of milliseconds.
4. public void join(): waits for a thread to die.
5. public void join(long miliseconds): waits for a thread to die for the specified miliseconds.
6. public int getPriority(): returns the priority of the thread.
7. public int setPriority(int priority): changes the priority of the thread.
8. public String getName(): returns the name of the thread.
9. public void setName(String name): changes the name of the thread.
10. public Thread currentThread(): returns the reference of currently executing thread.
11. public int getId(): returns the id of the thread.
12. public Thread.State getState(): returns the state of the thread.
13. public boolean isAlive(): tests if the thread is alive.
14. public void yield(): causes the currently executing thread object to temporarily pause and allow
other threads to execute.
15. public void suspend(): is used to suspend the thread(depricated).
16. public void resume(): is used to resume the suspended thread(depricated).
17. public void stop(): is used to stop the thread(depricated).
18. public boolean isDaemon(): tests if the thread is a daemon thread.
19. public void setDaemon(boolean b): marks the thread as daemon or user thread.
20. public void interrupt(): interrupts the thread.
21. public boolean isInterrupted(): tests if the thread has been interrupted.
22. public static boolean interrupted(): tests if the current thread has been interrupt
Multi-threading: -Multi-threading is a process to execute multiple thread at the same
time without depending of other thread called multi-threading.

A thread is a lightweight sub-process, the smallest unit of processing. Multiprocessing


and multithreading, both are used to achieve multitasking. However, we use
multithreading than multiprocessing because threads use a shared memory area. They don't
allocate separate memory area so saves memory, and context-switching between the threads
takes less time than process.

Java Multithreading is mostly used in games, animation, etc

Advantages of Java Multithreading

1) It doesn't block the user because threads are independent and you can perform multiple
operations at the same time.

2) You can perform many operations together, so it saves time.

3) Threads are independent, so it doesn't affect other threads if an exception occurs in a


single thread.

Difference between Multi tasking and Multithreading

S.NO Multitasking Multithreading

While in multithreading, many threads are


In multitasking, users are allowed to
1. created from a process through which
perform many tasks by CPU.
computer power is increased.

Multitasking involves often CPU While in multithreading also, CPU switching


2.
switching between the tasks. is often involved between the threads.

In multitasking, the processes share While in multithreading, processes are


3.
separate memory. allocated the same memory.

The multitasking component involves While the multithreading component does


4.
multiprocessing. not involve multiprocessing.

While in multithreading also, a CPU is


In multitasking, the CPU is provided in
5. provided in order to execute many threads
order to execute many tasks at a time.
from a process at a time.

In multitasking, processes don’t share


While in multithreading, each process
6. the same resources, each process is
shares the same resources.
allocated separate resources.
Thread life cycle:-

1. New State(Born)
2. Active State(Ready)
3. Running State(Execution)
4. Waiting state(Blocked)
5. Dead state(Exit)

 Any thread in java is controlled by JVM


 When directly does not execute any program, it does it through the command.

You might also like