Java核心概念之面向对象编程OOP
-
类
-
就是模板,用来定义一类对象的方法和属性,比如人、学生、动物、猫,万物都是有模板,都是可以定义为类。
-
类名首字母大写
kotlinclass Person { }
-
-
对象
-
类的实例化,比如 学生这个类实例化,就是 XX同学
iniPerson person = new Person(); new Persion();
-
-
方法
-
方法是语句的集合,在一起完成一个功能
-
方法包含于类或对象中,即普通方法或者类方法
kotlin修饰符 返回值类型 方法名(参数类型 参数名) { ... 方法体 ... return 返回值; }
-
-
继承
- 子类继承父类的特征和行为,使得子类对象具有父类的方法和属性
- 父类也叫基类,具有公共的方法和属性
-
多态
- 同一个行为具有多个不同表现形式的能力
- 优点:减少耦合、灵活可拓展
- 一般是继承类或者重写方法实现
-
抽象
- 关键词abstract声明的类叫作抽象类,abstract声明的方法叫抽象方法
- 一个类里包含了一个或多个抽象方法,类就必须指定成抽象类
- 抽象方法属于一种特殊方法,只含有一个声明,没有方法体
Java面向对象的中的构造函数和方法封装
-
什么是构造函数
- 一种特殊的方法,创建对象时用来初始化对象,每次使用new 创建对象的时候,就会使用构造函数
- 与类具有相同的名称,但是没有返回值,Java会自动为每个类提供一个默认构造函数
- 如果自己定义了构造函数,就不再使用默认构造函数,如果没有显示的写出默认构造函数,则会消失
- 注意点:如果构造函数之间互相调用,务必写在方法第一行
-
构造函数种类
-
默认构造函数(也叫无参构造函数)
arduinopublic 类名() { } -
无参构造函数
arduinopublic 类名() { } -
有参构造函数
arduinopublic 类名(参数类型1 参数名1,参数类型2 参数名2...) { }
-
-
构造函数的修饰符
- public 用的最多,用来创建对象
- private 私有化构造函数,不给外部创建对象,比如工具类,或者单例设计模式
- default 默认的话,只能在当前包里面使用new 创建对象,几乎不用
-
封装
- 封装是把过程和数据包围起来,对数据的访问只能通过已定义的接口即方法
- 在java中通过关键字private,protected和public实现封装。
- 什么是封装?封装把对象的所有组成部分组合在一起,封装定义程序如何引用对象的数据
- 封装实际上使用方法将类的数据隐藏起来,控制用户对类的修改和访问数据的程度。
- 适当的封装可以让代码更容易理解和维护,也加强了代码的安全性
- 包括:类封装、方法封装
-
overload(重载,过载)
-
在一个类里面,方法名字相同,而参数不同,和返回类型无关
-
方法名必须相同。
-
参数列表必须不同(参数类型、参数个数、参数顺序)。
-
方法的返回类型可以相同也可以不同。
-
重载与方法的访问修饰符和是否为static无关。
csharp// 无参数方法 public void display() { System.out.println("Display method with no parameters."); } // 一个整型参数的方法 public void display(int num) { System.out.println("Display method with int parameter: " + num); } // 一个字符串参数的方法 public void display(String str) { System.out.println("Display method with String parameter: " + str); }
-
-
override(重写,覆盖)
-
子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变
-
包括:返回值类型,方法名,参数类型以及个数
-
子类能够根据需要实现父类的方法
csharp// override(重写,覆盖) @Override public void makeSound() { System.out.println("喵"); }
-
Java面向对象核心关键字this
-
this关键字
- 在Java中,
this是一个特殊的引用变量,它引用当前对象本身。 - 在类的内部,你可以使用
this来引用对象的当前实例的变量和方法。 this关键字的主要用途有:- 区分成员变量和局部变量
- 在构造方法中引用其他构造方法通过
this()
- 在Java中,
-
注意事项
this不能在静态方法中使用,因为静态方法不属于类的任何实例。this引用的是当前对象的内存地址,而不是它的值。this只能在构造方法或实例方法中使用,不能在类方法中(静态方法)使用。- 如果在构造方法中没有显式地使用
this来调用另一个构造方法,则会自动调用无参数的构造方法(如果存在) - 但如果在构造方法中已经使用了
this()来调用另一个构造方法,则不能再调用另一个构造方法或默认构造方法。
-
例:
csharppublic class ThisExample { private int x, y; public ThisExample(int x) { this(x, 0); } public ThisExample(int x, int y) { this.x = x; this.y = y; } public void printXY() { System.out.println("x:" + x + ",y:" + y); } public static void main(String[] args) { ThisExample thisExample = new ThisExample(1); thisExample.printXY(); } }
面向对象编程之继承extend
-
继承
- 子类继承父类的特征和行为,使得子类对象具有父类的方法和属性
- 父类也叫基类,具有公共的方法和属性,生活中的例子
- java中的继承,减少重复代码
-
格式,通过extends关键字
scalaclass 父类名称 { } class 子类名称 extends 父类名称 { } -
特点
- 子类拥有父类的非private的属性和方法
- 子类可以用自己的方式实现父类的方法 override(重写,覆盖)
- 实现了代码的复用,重写从父类那里继承来的方法的,当调用方法时候会优先调用子类的方法(默认就近原则)
-
构造方法和继承
- 子类不能继承父类的构造方法,但子类在创建对象时会自动调用父类的构造方法(如果父类有默认构造方法)。
- 如果父类没有无参数的构造方法,而子类构造方法中又没有显式调用父类的构造方法,则编译会出错。
- 子类可以通过
super()关键字显式调用父类的构造方法,且super()调用必须位于子类构造方法的第一行。
-
注意
- 不支持多继承,支持多重继承,多重继承提高了耦合性,组合优于继承
- 所有的类都是继承于 java.lang.Object
- final关键字
- 修饰的类,则这个类不可以被继承
- 修饰方法,则这个方法不允许被覆盖(重写)
Java面向对象编程之继承的super关键字
-
super关键字
- 一个引用变量,用于引用父类对象
- 父类和子类都具有相同的命名方法,要调用父类方法时使用
- 父类和子类都具有相同的命名属性,要调用父类中的属性时使用
- super也是父类的构造函数,格式 super(参数)
- 注意点 调用super() 必须是类构造函数中的第一条语句,否则编译不通过
-
注意
-
每个子类构造方法的第一条语句,都是隐含地调用super(),如果父类没有这种形式的构造函数,那么在编译的时候就会报错
scalapublic class Animal { public Animal() { System.out.println("Animal无参构造函数"); } } public class Cat extends Animal { public Cat() { // super(); System.out.println("Cat无参构造函数"); } } -
this()和super()都指的是对象,均不可以在static环境中使用
- 包括:static变量,static方法,static语句块。
-
-
构造函数里面的 super和this
- this 和super在构造函数中只能有一个,且都必须是构造函数当中的第一行
- 当父类的构造函数是无参构造函数时,在子类的构造函数中,不用显式super()去调用父类的构造函数,
- 当父类的构造函数是有参构造函数时,如果子类的构造函数中不写super()进行调用父类的构造函数,编译器会报错
-
java继承后类的初始化顺序
- 静态代码块、非静态代码、父类/子类无参构造方法、父类/子类的一般方法
-
例:
csharppublic class Animal { static { System.out.println("Animal静态代码块"); } // 默认构造函数(无参构造函数) public Animal() { System.out.println("Animal无参构造函数"); } // 有参构造函数 public Animal(String name) { this.name = name; } // 有参构造函数 public Animal(int age) { this.age = age; } // 有参构造函数 public Animal(String name, int age) { this.name = name; this.age = age; } private String name; private int 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 eat() { System.out.println("吃饭"); } public void sleep() { System.out.println("睡觉"); } public void makeSound() { System.out.println("叫"); } }csharppublic class Cat extends Animal { static { System.out.println("Cat静态代码块"); } public Cat() { // super(); System.out.println("Cat无参构造函数"); } public Cat(String name) { super(name); } public Cat(int age) { super(age); } public Cat(String name, int age) { super(name, age); } public void catchMice() { System.out.println("抓老鼠"); } // override(重写,覆盖) @Override public void makeSound() { System.out.println("喵"); } }inipublic class ExtendDemo { public static void main(String[] args) { Cat cat1 = new Cat(); Cat cat2 = new Cat("墩墩", 2); System.out.println(cat2.getName()); System.out.println(cat2.getAge()); cat2.eat(); cat2.sleep(); cat2.catchMice(); } }Animal静态代码块 Cat静态代码块 Animal无参构造函数 Cat无参构造函数 墩墩 2 吃饭 睡觉 抓老鼠
Java面向对象编程之抽象abstract
-
抽象
- 当父类的某些方法不确定时,可以用abstract关键字来修饰该方法,即抽象方法,用abstract来修饰该类,即抽象类
- 抽象类将事物的共性的东西提取出来,由子类继承去实现,代码易扩展、易维护
- java中的抽象类和抽象方法
-
抽象特点:
- 抽象类的特点
- 抽象类不能被实例化,因为抽象类中方法未具体化,这是一种不完整的类,所以不能直接实例化,编译无法通过
- 抽象类中不一定包含抽象方法,但是有抽象方法的类必定是抽象类
- 如果一个抽象类中可以没有抽象方法,这样做的目的是为了此类不能被实例化。
- 抽象类的子类必须给出抽象类中的抽象方法的具体实现,否则子类也是抽象类,需要用abstract声明
- 抽象类不能使用final关键字修饰,因为final修饰的类是无法被继承
- 抽象方法的特点
- 抽象类中的抽象方法只是声明,不包含方法体
- 抽象方法不能用private修饰,因为抽象方法必须被子类实现(覆写),而private权限对于子类来说是不能访问的
- 一个类继承了一个抽象类,那么它必须全部覆写抽象类中的抽象方法当然也可以不全部覆写
- 如果不覆写全部抽象方法则这个子类也必须是抽象类
- 构造方法,类方法(即static 修饰的方法)不能声明为抽象方法
- 抽象类的特点
-
例:
csharp// 抽象类 abstract class Vehicle { // 抽象方法 public abstract void start(); public void stop() { System.out.println("停止运行"); } } class Car extends Vehicle { @Override public void start() { System.out.println("汽车运行"); } } public class AbstractDemo { public static void main(String[] args) { Vehicle car = new Car(); car.start(); car.stop(); } }
【新特性】Java面向对象编程之接口interface
-
接口
- 是抽象方法的集合,接口通常以interface来声明,一个类通过继承接口的方式,从而来继承接口的抽象方法
- Java 8及以后,还可以包含默认方法和静态方法,不包含方法的实现
- 作用
- 解耦:接口定义了对象之间的契约,使得不同类之间的交互更加清晰和灵活。
- 多重继承:通过实现多个接口,一个类可以继承多个接口中的方法,实现类似多重继承的功能。
- 定义规范:接口定义了一组方法的集合,实现了该接口的类必须遵循这些方法的定义。
-
接口定义
-
接口使用
interface来定义,接口中的方法都是隐式抽象的(不需要abstract关键字),且都是public的(没有明确指定)。csharppublic interface MyInterface { // 常量定义,默认是public static final的 int CONSTANT = 0; // 抽象方法定义,默认是public的 void method(); // Java 8及以后,接口可以包含静态方法 static void staticMethod() { System.out.println("MyInterface的静态方法"); } // Java 8及以后,接口可以包含静态方法 default void defaultMethod() { System.out.println("MyInterface的默认方法"); } }
-
-
接口实现
-
类可以使用
implements关键字来实现一个或多个接口 -
如果一个类实现了某个接口,那么它必须实现该接口中的所有抽象方法,除了默认方法和静态方法。
typescriptpublic class MyClass implements MyInterface { @Override public void method() { System.out.println("MyClass的方法"); } }
-
-
例:
csharppublic interface Shape { void draw(); void calculateArea(); }typescriptpublic class Circle implements Shape { @Override public void draw() { System.out.println("画圆"); } @Override public void calculateArea() { System.out.println("计算圆的面积"); } }typescriptpublic class Rectangle implements Shape { @Override public void draw() { System.out.println("画矩形"); } @Override public void calculateArea() { System.out.println("计算矩形的面积"); } }scsspublic class InterfaceDemo { public static void main(String[] args) { MyInterface myClass = new MyClass(); myClass.method(); myClass.defaultMethod(); MyInterface.staticMethod(); Shape circle = new Circle(); circle.draw(); circle.calculateArea(); Shape rectangle = new Rectangle(); rectangle.draw(); rectangle.calculateArea(); } } -
接口和抽象类区别
- 抽象类可以有方法的具体实现,而接口中的方法都是抽象的(除了默认方法和静态方法)。
- 抽象类可以有构造方法,而接口不能有构造方法。
- 一个类只能继承一个抽象类,但可以实现多个接口。
- 接口主要用于定义规范,而抽象类主要用于代码的复用
Java面向对象编程之InstanceOf关键字
-
InstanceOf 关键字
- 在Java中,
instanceof是一个运算符,用于测试对象是否是一个类的实例,或者对象的超类或接口的一个实例。 instanceof在运行时判断对象是否是一个类的实例,返回true或false。
typescriptpublic class InstanceOfDemo { public static void main(String[] args) { Object obj1 = 1; Object obj2 = "Hello World"; Object obj3 = new Cat(); System.out.println(obj1 instanceof Integer); System.out.println(obj2 instanceof String); System.out.println(obj3 instanceof Animal); System.out.println(obj3 instanceof Cat); } } - 在Java中,
-
注意事项
- 使用
instanceof时,要确保对象引用变量不是null,否则将会抛出NullPointerException。 - 在使用
instanceof进行类型判断后,如果需要进行类型转换,应该使用强制类型转换(如(ClassName) obj)。 - 尽量避免在代码中过度使用
instanceof,因为它可能会破坏面向对象的多态性
- 使用