Part5:面向对象编程
什么是面向对象
面向对象编程(Object-Oriented Programming, OOP)
面向对象编程的本质就是:以类的方式组织代码,以对象的方式封装数据。
从现实的角度:先有对象,再有类。对象是具体的事物,类是对对象的抽象。
从代码的角度:先有类,再有对象。类是抽象的模板,对象是类具体的实例。
类的基本构成:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| 修饰符 class 类名{ 修饰符 属性类型 属性名 = 属性值;
修饰符 类名(){ } 修饰符 返回值类型 方法名(){ return ...; } }
|
类与对象的创建
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| public class Student { String name; int age;
public static String study() { return "学习~"; }
public String sleep() { return "睡觉~"; } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| public class Application { public static void main(String[] args) {
Student xiaoming = new Student(); Student xiaohong = new Student();
xiaoming.name = "小明"; xiaoming.age = 10;
System.out.println(xiaoming.name); System.out.println(xiaoming.age);
xiaohong.name = "小红"; xiaohong.age = 11;
System.out.println(xiaohong.name); System.out.println(xiaohong.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
| package com.zhou.oop.Demo05;
public class Student { String name; int age;
public static String study() { return "学习~"; }
public String sleep() { return "睡觉~"; } }
|
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 com.zhou.oop;
import com.zhou.oop.Demo05.Student;
import java.io.IOException;
public class Demo01 { public static void main(String[] args) { int max = max(10, 10); System.out.println(max);
String s1 = Student.study(); System.out.println(s1);
Student student = new Student(); String s2 = student.study(); System.out.println(s2); }
public String sayHello() { return "Hello World"; }
public static int max(int a, int b) { return a>b ? a:b; }
public void readFile(String file) throws IOException{
} }
|
方法的重载
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
| package com.zhou.oop;
public class Demo02 { public static void main(String[] args) { double max = max(20, 10); System.out.println(max); }
public static int max(int num1, int num2) { int result = -1;
if (num1 > num2) { result = num1; System.out.println("num1>num2"); } else if (num1 == num2) { System.out.println("num1==num2"); return 0; } else { result = num2; }
return result; }
public static double max(double num1, double num2) { double result = 0;
if (num1 > num2) { result = num1; } else if (num1 == num2) { System.out.println("num1==num2"); return 0; } else { result = num2; } return result; } }
|
可变参数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| package com.zhou.oop;
public class Demo03 { public static void main(String[] args) { Demo03 demo03 = new Demo03(); demo03.test(1,2,3,4,5,6); }
public void test(int...i){ for (int j = 0; j < i.length; j++) { System.out.println(i[j]); } }
}
|
递归
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| package com.zhou.oop;
public class Demo04 { public static void main(String[] args) { int s = f(4); System.out.println("10!="+s); }
public static int f(int n){ if(n==1){ return 1; }else { return n*f(n-1); } } }
|
构造器详解
使用new关键字创建对象时,除了分配内存空间外,还会给创建好的对象进行默认的初始化,以及对类中构造器的调用。
类中的构造器也称为构造方法,是在进行创建对象时必须要调用的。并且构造器有以下两个特点:
- 必须和类的名字相同
- 必须没有返回类型,也不能写void
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 com.zhou.oop.Demo05;
public class Person {
String name; int age;
public Person(){ this.name = "guiyi"; }
public Person(String name, int age) { this.name = name; 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 30 31 32 33 34 35 36
| package com.zhou.oop.Demo05;
public class Application { public static void main(String[] args) {
Student xiaoming = new Student(); Student xiaohong = new Student();
xiaoming.name = "小明"; xiaoming.age = 10;
System.out.println(xiaoming.name); System.out.println(xiaoming.age);
xiaohong.name = "小红"; xiaohong.age = 11;
System.out.println(xiaohong.name); System.out.println(xiaohong.age);
System.out.println("===================================");
Person person = new Person(); System.out.println(person.name);
Person zhangfei = new Person("张飞",13); System.out.println(zhangfei.name); System.out.println(zhangfei.age); } }
|
封装、继承和多态
封装(数据的隐藏)
通常,应禁止直接访问一个对象中数据的实际表示,而应通过操作接口来访问,这称为信息隐藏。
封装的好处:
- 提高程序的安全性,保护数据
- 隐藏代码的实现细节
- 统一接口
- 系统可维护性增加了
概况一句话就是:属性私有,get/set
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 com.zhou.oop.Demo05;
public class Teacher { private String name; private int age;
public String getName() { return name; }
public int getAge() { return age; }
public void setName(String name) { this.name = name; }
public void setAge(int age) { if (age>=0 && age<=120){ this.age = age; }else{ System.out.println("年龄错误"); }; } }
|
1 2 3 4 5 6 7 8 9 10
| package com.zhou.oop.Demo05;
public class Application { public static void main(String[] args) { Teacher teacher = new Teacher(); teacher.setAge(130); System.out.println(teacher.getAge()); } }
|
继承和多态
继承是类和类之间的一种关系。除此之外,类和类之间的关系还有依赖、组合、聚合等。
继承关系的两个类,一个为子类(派生类),一个为父类(基类)。子类继承父类,使用关键字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
| package com.zhou.oop.Demo05;
public class Person {
public String name; protected int age; char sex; private int money = 1000_000_000; public double height = 1.7;
public Person(){ System.out.println("Person无参构造执行了"); }
public int getMoney() { return money; }
public void setMoney(int money) { this.money = money; } }
|
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
| package com.zhou.oop.Demo05;
public class Teacher extends Person{
private double height = 1.9; private String subject;
public Teacher(){ super(); System.out.println("Teacher无参构造执行了"); }
public Teacher(String subject){ this.subject = subject; }
public void teach(){ System.out.println("教你学java~"); }
public void test(double height){ System.out.println(height); System.out.println(this.height); System.out.println(super.height); }
}
|
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 com.zhou.oop.Demo05;
public class Application { public static void main(String[] args) { Teacher teacher = new Teacher(); teacher.name = "zhou"; teacher.age = 20; teacher.sex = '1';
System.out.println(teacher.getMoney());
teacher.test(1.5); } }
|
super注意点:
super()
调用父类的构造方法,必须在子类构造方法中的第一行,且不能和this()
同时调用
super.方法
或super.属性
必须只能出现在子类的方法或构造方法中
多态
Java的方法调用总是作用于运行期对象的实际类型,这种行为称为多态。
一个对象的实际类型是确定的,但可以指向对象的引用类型有很多(父类,有关系的类)。
多态存在的条件
- 有继承关系
- 子类重写父类的方法
- 父类引用指向子类对象
注意:多态是方法的多态,属性没有多态性
方法的重写
重写都是方法的重写,跟属性无关!
重写需要有继承关系,子类重写父类的方法!
- 方法名必须相同
- 参数列表必须相同
- 修饰符:范围可以扩大但不能缩小(
private
和final
无法被重写): public > Protected > Default > private
- 抛出的异常:范围可以被缩小,但不能扩大:
ClassNotFoundException(小) --> Exception(大)
为什么需要重写:
- 父类的功能,子类不一定需要,或者不一定满足
1 2 3 4 5 6 7 8 9
| package com.zhou.oop.Demo05;
public class B {
public void test() { System.out.println("B=>test()"); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| package com.zhou.oop.Demo05;
public class A extends B{
public void test() { System.out.println("A=>test()"); } }
|
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
| package com.zhou.oop.Demo05;
public class Application { public static void main(String[] args) { A a = new A();
B b = new A();
System.out.println("static静态方法无法被重写"); a.test1(); b.test1();
System.out.println("父类方法被子类重写后:"); a.test2(); b.test2(); } }
|
抽象类和接口
抽象类
abstract
修饰符可以用来修饰方法,也可以修饰类,如果修饰方法,那么该方法就是抽象方法;如果修饰类,那么该类就是抽象类。
抽象类中可以没有抽象方法,但抽象方法的类一定要声明为抽象类。
抽象类,不能使用new关键字来创建对象,它是用来让子类继承的。
抽象方法,只有方法的声明,没有方法的实现,它是用来让子类实现的。
子类继承抽象类,那么就必须要实现抽象类没有实现的抽象方法,否则该子类也要声明为抽象类。
1 2 3 4 5 6 7
| package com.zhou.oop;
public abstract class Demo06 { public abstract void doSomething(); }
|
接口
普通类:只有具体实现
抽象类:具体实现和规范(抽象方法)都有!
接口:只有规范!
接口就是规范,定义的是一组规则。
声明类的关键字是class
,声明接口的关键字是interface
1 2 3 4 5 6 7 8 9 10 11 12
| package com.zhou.oop.demo07;
public interface UserService {
void add(String name); void delete(String name); void update(String name); void query(String name);
}
|
Part6:异常处理
异常包括:抛出异常、捕获异常
异常处理五个关键字:try
, catch
, finally
, throw
, throws
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
| package com.zhou.exception;
public class Demo01 { public static void main(String[] args) { new Demo01().test(1,0); }
public void test(int a, int b){ if (b==0){ throw new ArithmeticException(); } } }
|