Java学习笔记(1)面向对象

1、Java面向对象中类与对象的概念和使用


方法的定义:

方法就是一段可以重复调用的代码。

定义格式:

1
2
3
访问修饰符 返回值类型 方法名(){
方法主体
}

方法的返回值类型:

void类型不需要返回值,其他类型的全部需要返回值。

方法的重载:

方法名称不同,但是参数的类型和个数相同,通过传递参数的个数和类型不同来完成不同的功能。

类的定义:

1
2
3
4
class 类名称{
属性
方法
}

声明一个类需要通过一个关键字class。

类与对象的关系:

类是对某一类事物的描述,是抽象的、概念上的意义,对象是实际存在的该类事物的每一个个体,也被称为对象或实例。

了解面向对象:

1、程序的发展历程:面向过程、面向对象。

2、解释面向过程和面向对象:(比如制作一个盒子)

  • 面向过程:不去想做什么样子的盒子,随机取工具制作。
  • 面向对象:先想好做一个什么样的盒子,再去找对应的工具去做。

面向对象的三大特征:

  1. 封装性:对外部不可见。
  2. 继承:扩展类的功能。
  3. 多态性:方法的重载。 对象的多态性。

方法的递归

递归调用就是方法自己调用自己。

例如:求1-100的和。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package java面向对象;

public class 递归调用 {

public static void main(String[] args) {
System.out.println(sum(100));
}
//求1-100的和
public static int sum(int n){
if (n == 1) //程序出口
return 1;
else
return n+sum(n-1);
}
}

2、Java面向对象的基本特征之一:封装性


封装性:

1、封装性的目的:保护某些属性和方法不被外部所看见。

2、封装的实现:为属性和方法进行封装是通过关键字private声明的。 实现该属性的set和get方法,为外部所访问。

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package java面向对象;
//private 实现分装,外部不可直接调用。
//get set 是外界访问的接口。
class Person{
private int age;
private String name;
public int getAge() {
return age;
}
public void setAge(int age) {
if (age>=0 && age<150) { //判断年龄是否合法。若非法显示为0
this.age = age;
}
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void tell(){ //get是得到
System.out.println("姓名:"+getName()+" 年齡:"+getAge());
}
}
public class 封装性 {
public static void main(String[] args) {
Person per = new Person();
per.setName("张三");//set是设置
per.setAge(30);
per.tell();
}
}

匿名对象:

匿名对象就是没有名字的对象,如果程序中只用一次该对象,就可以事业匿名对象的方式。

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package java面向对象;
class Student{
public void tell() {
System.out.println("hello");
}
}
public class 匿名对象 {
public static void main(String[] args) {
//正常对象
Student stu = new Student();
stu.tell();
//匿名对象
new Student().tell();//调用一次的情况可用匿名对象
}
}

构造方法:

1、格式:

1
2
3
访问修饰符 类名称(){
程序语句
}

2、注意点:

  1. 构造方法名称必须与类名一致。
  2. 构造方法没有返回值。

3、构造方法主要是为类中的属性初始化。

4、每个类在实例化之后都会调用构造方法,如果没有构造方法,程序在编译的时候回创建一个无参的什么都不做的构造方法。

5、构造方法也可以重载。

例如:

1
2
3
4
5
6
7
8
9
10
11
12
package java面向对象;
class People{
//构造方法
public People(int a) {
System.out.println(a);
}
}
public class 构造方法 {
public static void main(String[] args) {
People per = new People(5);
}
}

3、Java面向对象中引用的传递

引用传递:

也称为传地址。方法调用时,实际参数的引用(地址,而不是参数的值)被传递给方法中相对应的形式参数,在方法执行中,对形式参数的操作实际上就是对实际参数的操作,方法执行中形式参数值的改变将会影响实际参数的值。

值传递:

方法调用时,实际参数把它的值传递给对应的形式参数,方法执行中形式参数值的改变不影响实际参 数的值。

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package java面向对象;
class Ref{
String temp = "hello";
}
public class 引用传递 {
public static void main(String[] args) {
Ref r1 = new Ref();
System.out.println(r1.temp);
tell(r1);
System.out.println(r1.temp);
}
public static void tell(Ref r1) {
r1.temp = "word";
}
}

this关键字:

  1. 表示类中的属性和调用方法。
  2. 调用本类中的构造方法。
  3. 表示当前对象。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package java面向对象;
class People1{
String name;
int age;
public People1(String name,int age) {
this(); //this作用二:调用本类中构造方法
//注意:使用此调用,必须放在第一行
this.name=name; //this作用一:调用本类中属性name
this.age=age;
}
private People1() {
System.out.println("调用无参构造方法");
}
public void tell() {
System.out.println("姓名:"+this.name+" 年龄:"+this.age);
System.out.println(this); //this作用三:表示当前对象
}
}
public class this关键字 {

public static void main(String[] args) {
People1 p = new People1("张三",30);
p.tell();
}
}

static关键字:

  1. 使用static声明属性:static声明全局属性。
  2. 使用static声明方法:直接通过类名调用。
  3. 注意点:使用static方法的时候,只能访问static声明的属性和方法,而非static声明的属性和方法是不能被访问的。

4、Java面向对象基本特征:继承


继承的实现:

  1. 继承的基本概念:扩展父类的功能。
  2. Java中使用extends关键字完成继承。 class 子类 extends 父类 {}

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package java面向对象;

class People2{
String name;
int age;
public void tell() {
System.out.println("姓名:" +name+ "年龄:"+age);
}
}
//学生为人的子类,可以继承人的属性,姓名,年龄
class Student2 extends People2{
int score;
public void say() {
System.out.println("成绩:"+score);
}
}
public class 继承 {
public static void main(String[] args) {
Student2 s = new Student2();
s.age = 15;
s.name = "小明";
s.score = 89;
s.tell();
s.say();
}
}

继承的限制:

  1. 在Java中只允许单继承。
  2. 子类不能直接访问父类的私有地址。

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package java面向对象;
//只能进行单继承
//子类不能直接访问父类的私有地址。
class People3{
private int age; //封装为私有属性
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return age;
}
}
class Worker extends People3{ //Worker单继承People3

}
class PetWorker extends Worker{ //PetWorker单继承Worker
public void tell(int age) {
setAge(age); //子类通过get和set可调用父类私有地址
System.out.println(getAge());
}
}
public class 继承的限制 {

public static void main(String[] args) {
PetWorker p = new PetWorker();
p.tell(30);
}
}

子类对象的实例化:

在子类对象实例化之前,必须先调用父类中的构造方法,之后调用子类的构造方法。

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package java面向对象;
class Father{
public Father() {
System.out.println("父类的构造方法");
}
}
class Son extends Father{
public Son() {
System.out.println("子类的构造方法");
}
}
public class 子类对象的实例化 {

public static void main(String[] args) {
Son s =new Son(); //声明并实例化
}
}
程序执行结果:
父类的构造方法
子类的构造方法

继承方法的重写:

  1. 在继承中,也存在着重写的概念,其实就是定义了和父类同名的方法。
  2. 定义:方法名称相同,返回值类相同,参数也相同。
  3. 重写的限制:被子类重写的方法不能拥有比父类更加严格的访问权限。
  4. 访问权限:private<default<public

public、private、protected、default的区别:

首先就class之间的关系做一个简单的定义,对于继承自己的class,base class可以认为他们都是自己的子女,而对于和自己一个目录下的classes(即同一个包),认为都是自己的朋友friendly。

  1. public:public表明该数据成员、成员函数是对所有用户开放的,所有用户都可以直接进行调用
  2. private:private表示私有,私有的意思就是除了class自己之外,任何人都不可以直接使用,私有财产神圣不可侵犯嘛,即便是子女,朋友,都不可以使用。
  3. protected:protected对于子女、朋友来说,就是public的,可以自由使用,没有任何限制,而对于其他的外部class,protected就变成private。
  4. default:java的默认访问权限,当没有使用上面提到的任何访问限定词时,就使用它,这种权限通常被称为包访问权限,在这种权限下,类可以访问在同一个包中的其他类的成员,也即可以访问我们前面说的朋友,在包之外,这些成员如同指定了private。

java 变量作用域的修饰的作用范围:

  • public:类本身和任何包的任何类都访问
  • private 只有类本身可以访问,其他类想访问可以通过该类的成员方法访问如getter/setter
  • protected:保护的,这个和缺省的比较容易混淆,记住最主要区别是:protected可以在不同包的子类被访问,而friendly不可以。 protected可以在类本身、同包的子类,不同包的子类,同包的非子类 被访问
  • 缺省的:可以在类本身,同包的子类,同包的非子类 被访问。
同类 同包 不同包子类 不同包非子类
private
default
protected
public

super关键字:

强行调用父类的方法的执行。

super不一定在重写中使用,也可以表示哪些方法是从父类中继承而来的。

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package java面向对象;
class A{
void tell() {
System.out.println("父类的构造方法");
}
}
class B extends A{
void tell() { //方法的重写
super.tell(); //super强行调用父类的方法的执行
System.out.println("子类的构造方法");
}
}
public class 继承方法的重写 {
public static void main(String[] args) {
B b = new B();
b.tell();
}
}
程序执行结果:
父类的构造方法
子类的构造方法

重写与重载的区别:(重点)

NO 区别点 重载 重写
1 单词 Overloading Overriding
2 定义 方法名称相同,参数的类型和个数不同 方法名称、参数的类型个数、返回值全部相同
3 权限要求 对权限没要求 被重写的方法不能有比父类更加严格的权限
4 范围 发生在一个类中 发生在继承中

5、Java面向对象-抽象类与接口


final关键字:

1、final关键字在java中被称为完结器,表示终结的意思。

2、final使能声明类、方法。属性:

  • 使能final声明的类不能被继承。
  • 使能final声明的方法不能被重写
  • 使能final声明的变了变成常量。常量是不可以被修改的。

抽象类:

  1. 抽象类概念:包含一个抽象方法的类就是抽象类。

  2. 抽象方法:声明而未被实现的方法,抽象方法必须使用abstract关键字声明。

  3. 抽象类被子类继承,子类(如果不是抽象类)必须重写抽象类中的所有抽象方法。

  4. 定义格式:

  5. 1
    2
    3
    4
    5
    abstract class className{
    属性
    方法
    抽象方法
    }
  6. 抽象类不能直接实例化,要通过其子类进行实例化。

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package java面向对象;

abstract class Abs{ //抽象类也必须使用abstract声明
int age;
private void tell() {
}
//抽象方法,声明而未被实现的方法
public abstract void say();
}
class C extends Abs{
//抽象类被子类继承,子类(如果不是抽象类)必须重写抽象类中的所有抽象方法。而且方法必须实现。
public void say() {
System.out.println(20);
}
}
public class 抽象类 {
public static void main(String[] args) {
// Abs a = new Abs(); //抽象类不能被直接实例化
C c = new C(); //抽象类必须通过子类实例化
c.say();
}
}

接口的实现:

  1. 接口是Java中最重要的概念、接口可以理解为一种特殊的类,里面全部是由全局常量和公共的抽象方法所组成的。

  2. 接口的格式:

  3. 1
    2
    3
    4
    interface interfaceName{
    全局常量
    抽象方法
    }
  4. 接口的实现也必须通过子类,使用关键字implments,而且接口是可以多实现的。

  5. 一个子类可以同时继承抽象类和实现多接口。

  6. 一个接口不能继承一个抽象类,但是却可以通过extends关键字同时继承多个接口,实现接口的多继承。

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package java面向对象;

interface Ineter1{ //定义了一个接口1
public static final int AGE = 20; //定义全局常量,全局常量名称必须全部大写
public abstract void tell(); //定义一个抽象方法
}
interface Inter2{ //定义接口2
public abstract void say();
}
abstract class Abs3{ //定义抽象类
public abstract void print();
}
//一个子类同时继承抽象类和实现多接口
class D extends Abs3 implements Ineter1,Inter2{
public void tell() {} //复写接口内的抽象方法
public void say() {}
public void print() {}
}
//一个接口不能继承一个抽象类,但是却可以通过extends关键字同时继承多个接口,实现接口的多继承
interface Inter3 extends Inter2,Ineter1{
}
public class 接口的实现 {

public static void main(String[] args) {
//Inetr1 i = new Inetr1(); //接口的实例化必须通过子类。
D d= new D(); //实例化接口
d.tell();
d.say();
System.out.println(Ineter1.AGE);
}
}

6、Java面向对象多态性


多态性:

1、多态性的体现:方法的重载和重写。 对象的多态性。

2、对象的多态性:

  • 向上转型:程序会自动完成。 父类 父类对象 = 子类实例
  • 向下转型:强制类型转换。 子类 子类对象 = (子类)父类实例

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
package java面向对象;
//多态性的体现:方法的重载和重写。 对象的多态性。
class I{
public void tell1() {
System.out.println("I--tell1");
}
public void tell2() {
System.out.println("I--tell2");
}
}
class J extends I{
public void tell1() {
System.out.println("J==tell1");
}
public void tell3() {
System.out.println("J==tell3");
}
}
public class 多态性 {
public static void main(String[] args) {
//向上转型 程序会自动完成。 父类 父类对象 = 子类实例
// J j = new J();
// I i = j;
// i.tell1(); //执行tell1重写的
// i.tell2();
//向下转型:强制类型转换。 子类 子类对象 = (子类)父类实例
//必须先向上转型,才能向下转型
I i = new J(); //是对向上转型的缩写
J j = (J)i;
j.tell1();
j.tell2();
j.tell3();
}
}
程序执行结果:
J==tell1
I--tell2
J==tell3

instanceof关键字:

  • instanceof 运算符是用来在运行时指出对象是否是特定类的一个实例。instanceof通过返回一个布尔值来指出,这个对象是否是这个特定类或者是它的子类的一个实例。
  • 用法:result = object instanceof class
  • 参数:
  • Result:布尔类型。
  • Object:必选项。任意对象表达式。
  • Class:必选项。任意已定义的对象类。
  • 说明:
  • 如果 object 是 class 的一个实例,则 instanceof 运算符返回 true。如果 object 不是指定类的一个实例,或者 object 是 null,则返回 false。

    例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package java面向对象;
class A2{
}
class B2 extends A2{
}
public class instanceof关键字 {
public static void main(String[] args) {
A2 a2 = new A2();
System.out.println(a2 instanceof A2);
System.out.println(a2 instanceof B2);
//向上转型
A2 a3 = new B2();
System.out.println(a3 instanceof A2);
System.out.println(a3 instanceof B2);
}
}
程序执行结果:
true
false
true
true

抽象类的应用举例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
package java面向对象;

abstract class Person1{
private int age;
private String name;
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return age;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public Person1(String name,int age){
this.name = name;
this.age = age;
}
public abstract void want();
}
class Student1 extends Person1{
private int score;
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
public Student1(String name,int age,int score) {
super(name, age);
this.score = score;
}
public void want() {
System.out.println("姓名:"+getName()+" 年龄:"+getAge()+" 工资:"+getScore());
}
}
class Worker2 extends Person1{
private int maney;
public void setManey(int maney) {
this.maney = maney;
}
public int getManey() {
return maney;
}
public Worker2(String name, int age, int maney) {
super(name, age);
this.maney = maney;
}
public void want() {
System.out.println("姓名:"+getName()+" 年龄:"+getAge()+" 工资:"+getManey());
}
}
public class 抽象类的应用 {

public static void main(String[] args) {
Student1 s = new Student1("小明", 10, 100);
s.want();
Worker2 w = new Worker2("小明",30, 3000);
w.want();
}
}
程序执行结果:
姓名:小明 年龄:10 工资:100
姓名:小明 年龄:30 工资:3000

接口的应用举例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
package java面向对象;

interface USB{ //定义一个USB接口
void start(); //定义抽象方法
void stop();
}
class Computer{
public static void work(USB u) {
u.start();
System.out.println("工作中···");
u.stop();
}
}
class USBDesk implements USB{ //定义一个U盘设备
public void start() {
System.out.println("U盘开始工作");
}
public void stop() {
System.out.println("U盘结束工作");
}
}
class Printer implements USB{ //定义一个打印机设备
public void start() {
System.out.println("打印机开始工作");
}
public void stop() {
System.out.println("打印机结束工作");
}
}
public class 接口的应用 {

public static void main(String[] args) {
Computer.work(new USBDesk()); //模拟U盘通过USB接口连接电脑
Computer.work(new Printer()); //模拟打印机通过USB接口连接电脑
}
}
程序执行结果:
U盘开始工作
工作中···
U盘结束工作
打印机开始工作
工作中···
打印机结束工作

7、Java面向对象之泛型


认识泛型:

  1. 泛型是在JDK1.5 之后新增的新功能。泛型(Generic)。

  2. 泛型可以解决数据类型的安全性问题,他的主要原理,是在类声明的时候通过一个标识表示类中某个属性的类型或者是某个方法的返回值及参数类型。

  3. 格式:

  4. 1
    2
    3
    4
    访问权限 class 类名称<泛型,泛型···>{
    属性
    方法
    }
  5. 对象的创建: 类名称<具体类型> 对象名称 = new 类名称<具体类型>

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package java面向对象;
//表示经纬度,坐标x,y
class Point<T>{ //一般用T表示
private T x;
private T y;
public T getX() {
return x;
}
public void setX(T x) {
this.x = x;
}
public T getY() {
return y;
}
public void setY(T y) {
this.y = y;
}
}
public class 认识泛型 {
public static void main(String[] args) {
Point p = new Point<String>();
//需要什么类型的数据,就在尖括号中声明什么类型的数据
p.setX("经度为:10");
p.setY("纬度为:20");
System.out.println(p.getX()+" "+p.getY());
}
}

构造方法使用泛型:

构造方法可以为类中的属性初始化,那么如果类中的属性通过泛型指定,而又需要通过该构造方法设置属性内容的时候,那么构造方法得的定义与之前并无不同,不需要像声明类那样指定泛型。

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package java面向对象;

class Generic<T>{
private T value;
public Generic(T value) {
this.value = value;
}
public void setValue(T value) {
this.value = value;
}
public T getValue() {
return value;
}
}
public class 构造方法中使用泛型 {

public static void main(String[] args) {
//尖括号中的类型可以根据需要任意指定数据类型
Generic<Integer> g = new Generic(10);
System.out.println(g.getValue());
}
}

设置多个泛型:

设置多个泛型直接在< >添加多个泛型就可以了。

例如:

1
2
3
4
class G<K,T>{
private K key;
private T take;
}

通配符:

在泛型<>中填入”?” ,代表什么类型都可以匹配。

泛型接口:

  1. 在JDK1.5之后,不仅仅可以声明泛型类,也可以声明泛型接口,声明泛型接口和声明泛型类的语法类似,也是在接口的名称后面加上.
  2. 格式: interface 接口名称<泛型标识>

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package java面向对象;

interface Interface<T>{
public void say();
}
class Gin<T> implements Interface<T>{
public void say() {
System.out.println("泛型接口");
}
}
public class 泛型接口 {
public static void main(String[] args) {
Gin<String> g = new Gin<String>();
g.say();
}
}

泛型方法:

  1. 泛型方法中可以定义泛型参数,此时,参数的类型就是传入数据类型。
  2. 格式: 访问权限 <泛型标识> 泛型标识 方法名称([泛型标识 参数名称])

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package java面向对象;
//格式: 访问权限 <泛型标识> 泛型标识 方法名称([泛型标识 参数名称])
class Gener{
public <T>T tell(T t){
return t;
}
}
public class 泛型方法 {

public static void main(String[] args) {
Gener g = new Gener();
String str = g.tell("hello");
System.out.println(str);
int i = g.tell(10);
System.out.println(i);
}
}

泛型数组:

在使用泛型方法的时候,也可以传递过返回一个泛型数组。

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package java面向对象;

public class 泛型数组 {

public static void main(String[] args) {
String arr[] = {"hello","word","nihao"}; //字符串型数组
tell(arr);
Integer arr1[] = {1,2,3,4,5}; //整形数组
tell(arr1);
}
public static <T>void tell(T arr[]){
for(int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
}

坚持原创技术分享,您的支持将鼓励我继续创作!