2021_03_02_面向对象
面向对象编程
什么是面向对象
-
面向过程:
- 步骤清晰简单,第一步。。。第二步。。。
- 面对过程适合处理一些较为简单的问题
-
面向对象:
- 物以类聚。解决问题前先思考解决问题需要的分类。然后对分类进行单独思考。最后,对某个分类下的细节进行面向过程的思考
- 面向对象容易将复杂问题拆分。也因此适合多人协作完成问题的处理。
- 面向对象在宏观上能系统得分析问题,而在微观操作层面依然需要面向过程的思路去处理。
-
什么是面向对象编程
-
OOP, Object-Oriented Programming
-
面向对象编程的本质:
以类的方式组织代码,以对象组织(封装)数据。
-
抽象
-
三大特征:
- 封装
- 继承
- 多态
-
类是抽象的。对象,是从类演化而来的实例。
-
方法的回顾和加深
-
方法的定义:
- 修饰符
- 返回类型
- break和return的区别
- break:跳出循环,跳出switch
- return:方法结束,同时返回结果。返回结果要和返回类型对应。
- 方法名:命名规范,见名知意
- 参数列表:(参数类型, 参数名)
- 异常抛出:之后详解
-
方法的调用:
- 静态方法
- 非静态方法
// 学生类 public class Student { public static void main(String[] args) { } //学习,静态方法 public static void study(){ System.out.println("学生学习了"); } //说话,非静态方法 public void say(){ System.out.println("学生说话了"); } }import OOP.Student; public class Demo01 { public static void main(String[] args) { //调用静态方法学习 Student.study(); //调用非静态方法说话 Student student1 = new Student(); // 先实例话 student1.say(); // 在实例中使用说话方法 } } //学生学习了 //学生说话了- 形参和实参
- 值传递个引用传传递
- this关键字:表示当前类 (类似python的self)
对象的创建分析
-
创建与初始化对象
- 使用new关键词穿件对象
- 使用new关键词创建的时候,除了分配内存空间之外,还会给创建好的对象 进行默认的初始化
//学生类 public class Student { //属性 String name; int age; //方法 public void study(){ System.out.println(this.name + " is studying."); } }/执行文件 public class Application { //每个项目只需要一个主程式,一般包含在执行文件中 public static void main(String[] args) { //创建一个实例student1 Student student1 = new Student(); //设置student1的name student1.name = "XJY"; //设置student2的age student1.age = 18; //使用student1的study方法 student1.study(); } } //XJY is studying.- 类中的构造器也称为构造方法,在进行创建对象的时候必须要调用的。构造器有以下两个特点:
- 必须和类的名字相同
- 必须是没有返回类型,也不用写关键字void
public class Person {
String name;
//构造器 如果不定义则默认生成
//快捷键 alt+insert
public Person(String name){
//初始化name
this.name = name;
}
}
public class Application2 {
public static void main(String[] args) {
Person p1 = new Person("XJY");
System.out.println(p1.name);
}
}
//XJY
面向对象三大特征
-
封装
-
该露的露,该藏得藏:
程序设计讲究“高内聚,低耦合”
高内聚就是类的内部数据操作细节自己完成,不允许外部干涉
低耦合指的是仅仅暴露少量接口供外部使用
-
封装(数据的隐藏)
通常,应当禁止直接访问一个对象中数据的实际表示,而应该通过接口来访问,这样就能做到信息隐藏。
-
一句话:属性私有,get/set
-
public class Student {
//private 私有属性
private String name;
private int idNumber;
private boolean sex; //male - true; female - false
public Student() {
this.name = "XXX";
this.idNumber = 0;
this.sex = true;
}
public Student(String name, int idNumber, boolean sex) {
this.name = name;
this.idNumber = idNumber;
this.sex = sex;
}
//提供一些可以访问私有属性的方法
//提供一些public的get、set方法
//get
public String getName(){
return this.name;
}
public int getIdNumber(){
return this.idNumber;
}
public String getSex() {
if (this.sex) {
return "Male";
}else {
return "Female";
}
}
//set
public void setName(String name){
this.name = name;
}
public void setIdNumber(int idNumber) {
this.idNumber = idNumber;
}
public void setSex(String sex) {
if (sex.equals("Male")) {
this.sex = true;
} else if (sex.equals("Female")) {
this.sex = false;
}else {
System.out.println("性别录入失败");
}
}
//alt+inset 快捷键可以快速创建get set方法
}
public class Application {
public static void main(String[] args) {
boolean flag = true;
Student student1 = new Student();
student1.setName("XJY");
System.out.println("Name is " + student1.getName());
student1.setIdNumber(30);
System.out.println("ID is " + student1.getIdNumber());
student1.setSex("Female");
System.out.println("Sex is " + student1.getSex());
}
}
//Name is XJY
//ID is 30
//Sex is Female
-
继承
-
继承的本质是对某一批类的抽象,从而实现对现实世界更好的建模。
-
extends的意思是扩展。子类是父类的扩展。
-
JAVA中类只有单继承,没有多继承。
-
继承是类和类之间的一种关系,除此之外,类和类之间的关系还有依赖、组合、聚合等。
-
继承关系的两个类,一个是子类,一个是父类,子类继承父类用关键字extends来表示
-
子类和父类之间,从意义上讲应该具有“is a”的关系
-
object类,所有类都是object类的子类
-
super,调用父类构造器时使用的关键字
//人类 public class Person { //私用属性无法继承 private String name; int age; public Person() { this.name = "XXX"; this.age = 10; } public Person(String name, int age) { this.name = name; this.age = age; } public void setName(String name) { this.name = name; } public String getName() { return name; } public void say(){ System.out.println("人说话"); } }//学生类 is 人类 public class Student extends Person{ public Student() { super(); } public Student(String name, int age) { //使用super可以调用父类的构造器方法 必须在子类构造器的第一行 super(name, age); } }public class Application { public static void main(String[] args) { Student student1 = new Student("XJY", 10); student1.say(); System.out.println(student1.getName()); } } //人说话 //XJY-
方法重写:
需要有继承关系。子类重写父类的方法。
public class A { public void test(){ System.out.println("Test A"); } public void test2(){ System.out.println("Test2 A"); } }// 重写方法演示 public class B extends A{ //方法重写 @Override public void test(){ System.out.println("Test B"); } //alt+insert 可以直接调出override method的快捷功能 @Override public void test2() { System.out.println("Test2 B"); } }public class Application { public static void main(String[] args) { B object1 = new B(); //父类的引用可以指向子类 这里B为A的子类 A object2 = new B(); A object3 = new A(); object1.test(); object2.test(); object3.test(); object1.test2(); object2.test2(); object3.test2(); } } //Test B //Test B //Test A //Test2 B //Test2 B //Test2 A注意:
- 方法名必须相同
- 参数列表必须相同
- 修饰符:范围可以扩大不能缩小 public > protected > default > private:
- 抛出的异常:范围可以缩小,但不能扩大
-
-
多态
- 同一个方法可以根据发送的对象不同而采用不同的行为方式
- 一个对象的实际类型是确定的,但是可以指向对象的引用类型有很多
- 多态的存在条件:
- 有继承关系
- 子类重写父类的方法
- 父类引用指向子类对象
- 注意:多态是方法的多态,属性没有多态性。
public class Person { public void run(){ System.out.println("RUN"); } }public class Student extends Person { @Override public void run() { System.out.println("Student Run"); } public void goToSchool() { System.out.println("Go to School."); } }public class Application { public static void main(String[] args) { Student s1 = new Student(); Person s2 = new Student(); /* 一个对象的实际类型是确定的. 比如这里的s1以及s2确定属于Student类 但是应用类型可以不一样。这边s2引用的就是父类Person类 注意,只有父类才能被子类型引用,反过来是不行的 */ //子类重写父类,则都执行父类方法 s1.run(); s2.run(); //子类独有的方法只有引用了Student的实例才能使用 s1.goToSchool(); //通过强制转换类型,可以让s2也能调用子类的方法 ((Student) s2).goToSchool(); } } //Student Run //Student Run //Go to School. //Go to School.- 关键字 instanceof : 判断一个对象是什么类型
public class Person { }public class Student extends Person{ }public class Teacher extends Person{ }以上为三个类,Student和Teacher均为Person的子类,那么执行以下命令会发现
public class Application { public static void main(String[] args) { Object student1 = new Student(); System.out.println(student1 instanceof Student); System.out.println(student1 instanceof Person); System.out.println(student1 instanceof Object); System.out.println(student1 instanceof Teacher); System.out.println(student1 instanceof String); System.out.println("============"); Person student2 = new Student(); System.out.println(student2 instanceof Student); System.out.println(student2 instanceof Person); System.out.println(student2 instanceof Object); System.out.println(student2 instanceof Teacher); System.out.println("============"); Student student3 = new Student(); System.out.println(student3 instanceof Student); System.out.println(student3 instanceof Person); System.out.println(student3 instanceof Object); System.out.println("============"); } } //true //true //true //false //false //============ //true //true //true //false //============ //true //true //true //============ -
static修饰的方法个变量和类一起加载。
public class Student { //第二个执行 { System.out.println("匿名代码块"); } //第一个执行 但是只执行一次 static { System.out.println("静态代码块"); } //第三个执行 public Student() { System.out.println("构造器"); } public static void main(String[] args) { Student student1 = new Student(); System.out.println("===="); Student student2 = new Student(); } } //静态代码块 //匿名代码块 //构造器 //==== //匿名代码块 //构造器
抽象类和接口
-
抽象类
//抽象类 public abstract class Action { //抽象方法 约束 有人会帮我们实现 //只有方法名字 没有方法的实现 public abstract void doSomething(); }//继承了抽象类的类 必须实现抽象类中所有的方法 //除非该类也是抽象类 public class A extends Action{ @Override public void doSomething() { } } -
抽象类的特点:
- 不能实例化,只能子类继承
- 只有抽象类中才能定义抽象方法,但是抽象类中可以写普通方法
- 抽象类只是一种约束条件
- 抽象类相当于创建类的一个模板,能够提高开发效率
-
接口
- 普通类:只有具体实现; 抽象类:具体实现和规范都有 接口:只有规范
- 接口就是规范。定义的是一组规则。“如果你是。。则你必须能。。。”的思想。
- 接口的本质是契约,就像法律。制定好之后所有程序遵守。
- OO的精髓是对对象的抽象,最能体现这一点就是接口。
- 声明接口的关键字是interface
- 接口可以实现多继承
第一个接口,
//interface 接口 都需要一个实现类UserServiceIMPL (一般实现类以IMPL结尾) public interface UserService { //常量 public static final int IP = 1000876; //接口中的所有定义都是抽象的公开的 public abstract void user(); }第二接口,
public interface TimeService { void timer(); }//类可以实现接口 使用关键词implements //可以连接多个接口 //通过接口可以实现多继承 public class UserServiceIMPL implements UserService, TimeService{ @Override public void timer() { } @Override public void user() { } }
内部类
-
内部类
-
内部类就是在一个类的内部再定义一个类
-
成员内部类
public class Outer { //外部类定义部分 private int id = 10; public void out(){ System.out.println("From Outer"); } //定义内部类Inner public class Inner{ public void in(){ System.out.println("From Inner"); } //获得外部类的私有属性 public int getID(){ return id; } //获得外部类的方法 public void inOuter() { out(); } } }public class Application { public static void main(String[] args) { Outer outer1 = new Outer(); //通过实例化的outer1来实例化一个inner1 Outer.Inner inner1 = outer1.new Inner(); //访问自己的方法 inner1.in(); //访问获得来的外部类的方法 inner1.inOuter(); //方位获得来的外部类的私有属性 System.out.println(inner1.getID()); } } //From Inner //From Outer //10 -
静态内部类
public class Outer { //外部类定义部分 private int id = 10; public static void out(){ System.out.println("From Outer"); } //定义静态内部类Inner 和类一起加载 public static class Inner{ //静态方法 public static void in(){ System.out.println("From Inner"); } //无法获得外部类的私有属性 因为和类一起加载时还没有定义id //无法获得非静态的外部类的方法 //但可以获得静态的外部类 public void inOut(){ out(); } } }public class Application { public static void main(String[] args) { //直接调用静态类的静态方法 无需实例化 Outer.Inner.in(); //可以直接使用new关键字来实例化一个inner1 Outer.Inner inner1 = new Outer.Inner(); //调用传递过外部静态方法的内部方法 inner1.inOut(); } } //From Inner //From Outer -
局部内部类
public class Outer { public void method(){ //在方法中可以定义局部内部类 class Inner{ public void in(){ System.out.println("From Inner"); } } } } -
匿名内部类
public class Test { public static void main(String[] args) { //实例不保存在变量中,没有初始化类直接调用其中的方法 new Apple().showColor(); //省去实现接口的类的名字,直接通过接口实例化一个service1 UserService service1 = new UserService(){ @Override public void hello() { System.out.println("Hello"); } }; service1.hello(); } } class Apple { public void showColor(){ System.out.println("Red"); } } interface UserService { void hello(); } //Red //Hello -
并行类
public class ClassA { } //一个java文件可以有多个类或接口 但只能有一个public的类 class ClassB{ } interface UserService{ }
-
浙公网安备 33010602011771号