点击勘误issues (opens new window),哪吒感谢大家的阅读

# 面向对象

  • 基本概念
  • 类和对象
  • 构造方法
  • this和super的用法
  • 对象数组
  • 对象间的关系
  • 封装
  • 继承
  • 多态
  • static
  • final
  • 修饰符的作用范围
  • 抽象类
  • 接口
  • 内部类

# 面向对象概述

程序发展:非结构化程序设计-》结构化程序设计-》面向对象程序设计

类和对象

# 类的定义

package ...;

// Person:用于描述整个人类的公共特征
// 一个类由两个部分来组成:人类的静态特征(属性),人类的动态行为(方法)
// 先定义类,再由类来创建对象
public class Person {
 String name;
 int age;

 public void speak() {
  System.out.println("会说话");
 }

 public void walk() {
  System.out.println("会走路");
 }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 创建对象

// 创建一个人出来
Person p = new Person();
p.name = "张三"
p.age = 20;

// 方法也是通过对象,来调用
p.desc();

Person p2 = new Person();
p2.desc();
1
2
3
4
5
6
7
8
9
10

# 无参构造方法

构造方法:如果一个类中没有写任何构造方法,则默认有无参的构造方法。

构造方法是一种特殊的方法

  1. 写法上:名称和类名必须一致,没有返回值类型
  2. 作用上:用于创建对象
public class Person {
 String name;
 int age;
 
 public Person() {
  System.out.println("我是无参构造方法");
 }
}
1
2
3
4
5
6
7
8

# 有参构造方法

// 一般方法也是属于具体某个对象的
// 构造方法:
// 1.如果一个类中没有写任何构造方法,则默认有无参的构造方法。
// 2.如果提供了其他构造方法,则默认的无参构造不再提供

// 构造方法是一种特殊的方法
// 1. 写法上:名称和类名必须一致,没有返回值类型
// 2. 作用上:用于创建对象
pubic class Person {
 String name;
 int age;

 public Person() {
  // System.out.println("我是无参构造方法")
 }
 
 public Person(String n) {
  name = n;
 }
 
 public Person(String n, int a) {
  name = n;
  age = a;
 }
}
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 ...
public class Test {
 public static void main(String[] args) {
  Person p = new Person("张三", 20);
  p.desc();
  
  Person p2 = new Person("李四");
  p2.age = 20;
  p2.desc();
  
 }
}
1
2
3
4
5
6
7
8
9
10
11
12

重载:

  1. 方法名相同,方法参数不同,称为方法的重载
  2. 方法参数不同,参数个数不同,类型不同,顺序不同

# 构造方法的相互调用

// this(参数) 表示对本类其他构造方法的调用
public class Person {
 String name;
 int age;
 
 public Person() {
  this("张三", 20);
 }
 
 public Person(String n) {
  name = n
 }
 
 // 全参构造
 public Person(String n, int a) {
  // this(n)
  name = n;
  age = a;
 }
 
 public void speak() {
  // ...
 }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package ...;

public class Test {
 public static void main(String[] args) {
  // Person p = new Person("张三", 20);
  // p.desc();
  Person p = new Person();
  p.desc();
 }
}
1
2
3
4
5
6
7
8
9
10

构造方法的相互调用问题:要避免死循环

  1. this(参数)表示对本类其他构造方法的调用
  2. this. 来调用本类的属性 或 方法
public class Person {
 String name;
 int age;
 public Person() {}
 
 public Person(String n) { name = n }
 
 public Person(String name, int age) {
  this.name = name;
  this.age = age;
 }
}
1
2
3
4
5
6
7
8
9
10
11
12

# this用法理解

# 对象数组的使用

# 对象间的关系

package ...;
public class Person {
 String name;
 int age;
 Person child;
 
 public Person() {
 }
 
 public Person(String name, int age) {
  this.name = name;
  this.age = age;
 }
 
 pubic Person(String name, int age, Person child) {
  this.name = name;
  this.age = age;
  this.child = child;
 }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# 引用传递

public class Test {
 public static void main(String[] args) {
  // 引用存在于栈中,对象存在于堆中
  Person p = new Person("张三", 20);
  Person p2 = p;
  // new: 用于开辟堆内存空间,创建对象
  p2 = new Person("李四", 20);
  System.out.println(p.name); // 张三
  System.out.println(p2.name); // 李四
 }
}
1
2
3
4
5
6
7
8
9
10
11

# 封装

public class Person {
 private String name;
 private int age;
 
 public Person() {
 }
 
 public Person(String name, int age) {
  this.name = name;
  this.age = age;
 }
 
 public int getAge() {
  return this.age;
 }

 public void setAge(int age) {
  if(age<0){
   this.age = 0;
  }else{
   this.age = age;
  }
 }
 
 public void desc() {
  System.out.println("") 
 }
}
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 ...;

public class Test {
 public static void main(String[] args) {
  Person p = new Person();
  p.setAge(-20);
  
  System.out.println(p.getAge());
 
  Person p2 = new Person("李四", -20);
  p2.desc();
 }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
package ...;

public class Person {
 private String name;
 private int age;
 public Person() {
 }
 
 public Person(String name, int age) {
  this.name = name;
  this.age = age;
 }
 
 public String getName() {
  return name
 }
 
 public void setName(String name) {
  this.name = name
 }

 public int ageAge() {
  return age
 }
 
 public void setAge(int age) {
  this.age = age;
 }
}
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

# 完全封装

  1. 属性全部私有
  2. 提供统一的访问方式
  3. 提供无参和全参构造
  4. 实现序列化接口

# 封装后的对象间关系

# 封装练习

  1. 电商购物项目 Java类Goods, 然后创建Goods对象并赋值为以下值。
goodsId: 商品编号
goodsName: 商品中文名
goodsEnglishName: 商品英文名
goodsThumb: 商品缩略图下载地址
goodsImg: 商品大图下载地址
addTime: 商品上架时间,单位
1
2
3
4
5
6

# Goods.java

public class Goods {
 private long goodsId;
 private String goodsName;
 private String goodsEnglishName;
 private String goodsThumb;
 private String goodsImg;
 // 强制类型转换 或者 使用大范围的类型
 private long addTime = 133435400000L;
}
1
2
3
4
5
6
7
8
9

# TestTime.java

package ...;
public class Test {
 public static void main(String[] args) {
  // 当前时间距离1970年1月1号0:0:0时间差的毫秒值
  long l = System.currentTimeMillis();
  System.out.println(l);
 }
}
1
2
3
4
5
6
7
8

基本数据类型:

  1. 整数:byte(1) short(2) int(4) long(8)
  2. 浮点型:float, double
  3. 布尔类型:boolean
  4. 字符类型:char

引用数据类型:类,接口,数组,枚举等

完全封装:1.属性全部私有;2.提供get和set;3.提供无参和全参构造;4.实现序列化接口

package ...;

public class Circle {
 private double r;
 private Point point;
 // 2*r
 public double getC() {
  return 2*Math.PI*this.r;
 }
}
1
2
3
4
5
6
7
8
9
10
Point p1 = new Point(2,3);
Point p2 = new Point(3,4);
double d = p1.getDistance(p2);
1
2
3

# 继承

使用extends关键字

public class Person {
 private String name;
 private int age;
 public Person() {}
 public Person(String name, int age) {
  this.name = name;
  this.age = age;
 }
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 public int getAge() {
  return age;
 }
 public void setAge(int age) {
  this.age = age;
 }
 public void desc() {
  System.out.println(name+":"+age);
 }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

student

// student 
public class Student extends Person {
 private String sno;
 public String getSno() {
  return sno;
 }
 public void setSno(String sno) {
  this.sno = sno;
 }
}
1
2
3
4
5
6
7
8
9
10

# super

super:指向父类对象

使用super(参数)调用父类的构造方法

super.setName(name);

// student继承自person
public class Student extends Person {
 public Student() {
  super();
 }
 public Student(String name, int age, String sno) {
  // super();
  super(name, age);
  this.sno = sno;
 }
}
1
2
3
4
5
6
7
8
9
10
11
12
13

# 重写

  1. 发生在父子类之间
  2. 同名同参同返回

override

# 单根继承即Object的理解

# toString的重写

java.lang
类 Object
java.lang.Object
public class Object
类Object是类层次结构的根类。每个都使用Object作为超类。所有对象都实现这个类的方法。
1
2
3
4
5

# hashcode 和 equals 的重写

# 多态

多态,一个表现,两条定理

  1. 当发生多态时,引用只能调用父类的方法,不能调用子类的方法。
  2. 当发生多态时,如果调用的方法子类进行了重写,则会调用子类重写之后的方法。

# 多态的理解

编译,运行

# 多态中的类型转换

public class Test {
 public static void main(String[] args) {
  Animal d = new Dog();
  d.eat();

  if (d instanceof Dog) {
   Dog d2 = (Dog)d;
   d2.dogMethod();
  }
 }
}
1
2
3
4
5
6
7
8
9
10
11

# 使用多态的好处

# 抽象方法 和 抽象类

public abstract double getTotalSal();
1

如果一个类中有抽象方法,则该类必须声明为抽象的,如果不声明为抽象的,则必须重写父类的所有抽象方法。

package ...;

public class A extends Emp {
 @Override
 public double getTotalSal() {
  return this.getSal()*12+1
 }
}
1
2
3
4
5
6
7
8

# abstract 总结说明

package ...;

public abstract class Emp {
 private int id;
 private String name;
 private double sal;
 
 public Emp() {
  super();
 }

 public Emp(int id, String name, double sal) {
  super();
  this.id = id;
  this.name = name;
  this.sal = sal;
 }
 
 public int getId() {
  return id;
 }

 public void setId(int id) {
  this.id = id
 }
  
 public String getName() {
  return name;
 }
 
 public void setName(String name) {
  this.name = name;
 }
 
}
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

abstract: 抽象的

  1. 如果一个类中有抽象方法,则该类必须声明为抽象的,如果不声明为抽象的,则必须重写父类的所有抽象方法。

抽象方法:

  1. 不知道具体该写什么,就写成抽象的,让子类去自己定义(重写)就可以。
  2. 抽象方法是一种标准,强制要求非抽象子类必须重写。

抽象类:

  1. 抽象类中可以有非抽象方法,也可以有抽象方法,或者只有其一。

# 抽象类 和 接口

接口

  1. 接口不是类,只是可以看作是一种特殊的抽象类
  2. 类和类是继承关系,是单继承关系,接口和类是实现关系,接口和接口之间是继承关系,并且是多继承关系
  3. 接口没有构造方法和抽象类一样,只能通过子实现类通过多态来调用

JDK1.8之前:

  1. 接口中所有的方法,都是public abstract 修饰的抽象方法。
  2. 接口中所有的字段(属性)都是public static final修饰的常量。

# static

# final

final: 不可变的,最终的

  1. 修饰属性,表示必须给属性赋值,并且该属性的值不能再变化。和static修饰的属性称为不可变的变量(常量)
  2. 修饰方法,表示该方法不能被重写。
  3. 修饰类,表示该类不能继承,那么所有的方法都不能被重写。
  4. 修饰局部变量。

# 成员内部类 和 静态内部类

内部类:

  1. 可以共用一些数据
  2. 该类只在它所在的外部类中使用

成员内部类,静态内部类,局部内部类,匿名内部类

# 匿名内部类

# 内部类使用练习

package ...;

import javax.swing.JFrame;
public class MyFrame extends JFrame {
 public MyFrame() {
  setBounds(200, 200, 200, 300);
  setVisible(true);
  setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 }
 
 public static void main(String[] args) {
  new MyFrame();
 }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 面向对象总结

对象分类 产生 类,考虑类的安全和方便,有了封装;为了代码复用,有了继承;父子类才能有重写,重写是多态的前提。

上次更新: 2/27/2022, 10:20:20 PM