Java面向对象编程OOP核心知识
Java核心概念之面向对象编程OOP类就是模板用来定义一类对象的方法和属性比如人、学生、动物、猫万物都是有模板都是可以定义为类。类名首字母大写class Person { }对象类的实例化比如 学生这个类实例化就是 XX同学Person person new Person(); new Persion();方法方法是语句的集合在一起完成一个功能方法包含于类或对象中即普通方法或者类方法修饰符 返回值类型 方法名(参数类型 参数名) { ... 方法体 ... return 返回值; }继承子类继承父类的特征和行为使得子类对象具有父类的方法和属性父类也叫基类具有公共的方法和属性多态同一个行为具有多个不同表现形式的能力优点减少耦合、灵活可拓展一般是继承类或者重写方法实现抽象关键词abstract声明的类叫作抽象类abstract声明的方法叫抽象方法一个类里包含了一个或多个抽象方法类就必须指定成抽象类抽象方法属于一种特殊方法只含有一个声明没有方法体Java面向对象的中的构造函数和方法封装什么是构造函数一种特殊的方法创建对象时用来初始化对象每次使用new 创建对象的时候就会使用构造函数与类具有相同的名称但是没有返回值Java会自动为每个类提供一个默认构造函数如果自己定义了构造函数就不再使用默认构造函数如果没有显示的写出默认构造函数则会消失注意点如果构造函数之间互相调用务必写在方法第一行构造函数种类默认构造函数(也叫无参构造函数)public 类名() { }无参构造函数public 类名() { }有参构造函数public 类名(参数类型1 参数名1参数类型2 参数名2...) { }构造函数的修饰符public 用的最多用来创建对象private 私有化构造函数不给外部创建对象比如工具类或者单例设计模式default 默认的话只能在当前包里面使用new 创建对象几乎不用封装封装是把过程和数据包围起来对数据的访问只能通过已定义的接口即方法在java中通过关键字privateprotected和public实现封装。什么是封装封装把对象的所有组成部分组合在一起封装定义程序如何引用对象的数据封装实际上使用方法将类的数据隐藏起来控制用户对类的修改和访问数据的程度。适当的封装可以让代码更容易理解和维护也加强了代码的安全性包括类封装、方法封装overload重载过载在一个类里面方法名字相同而参数不同和返回类型无关方法名必须相同。参数列表必须不同参数类型、参数个数、参数顺序。方法的返回类型可以相同也可以不同。重载与方法的访问修饰符和是否为static无关。// 无参数方法 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重写覆盖子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变包括返回值类型方法名参数类型以及个数子类能够根据需要实现父类的方法// override重写覆盖 Override public void makeSound() { System.out.println(喵); }Java面向对象核心关键字thisthis关键字在Java中this是一个特殊的引用变量它引用当前对象本身。在类的内部你可以使用this来引用对象的当前实例的变量和方法。this关键字的主要用途有区分成员变量和局部变量在构造方法中引用其他构造方法通过this()注意事项this不能在静态方法中使用因为静态方法不属于类的任何实例。this引用的是当前对象的内存地址而不是它的值。this只能在构造方法或实例方法中使用不能在类方法中静态方法使用。如果在构造方法中没有显式地使用this来调用另一个构造方法则会自动调用无参数的构造方法如果存在但如果在构造方法中已经使用了this()来调用另一个构造方法则不能再调用另一个构造方法或默认构造方法。例public 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关键字class 父类名称 { } class 子类名称 extends 父类名称 { }特点子类拥有父类的非private的属性和方法子类可以用自己的方式实现父类的方法override(重写覆盖)实现了代码的复用重写从父类那里继承来的方法的当调用方法时候会优先调用子类的方法默认就近原则构造方法和继承子类不能继承父类的构造方法但子类在创建对象时会自动调用父类的构造方法如果父类有默认构造方法。如果父类没有无参数的构造方法而子类构造方法中又没有显式调用父类的构造方法则编译会出错。子类可以通过super()关键字显式调用父类的构造方法且super()调用必须位于子类构造方法的第一行。注意不支持多继承支持多重继承多重继承提高了耦合性组合优于继承所有的类都是继承于 java.lang.Objectfinal关键字修饰的类则这个类不可以被继承修饰方法则这个方法不允许被覆盖重写Java面向对象编程之继承的super关键字super关键字一个引用变量用于引用父类对象父类和子类都具有相同的命名方法要调用父类方法时使用父类和子类都具有相同的命名属性要调用父类中的属性时使用super也是父类的构造函数格式 super(参数)注意点 调用super() 必须是类构造函数中的第一条语句否则编译不通过注意每个子类构造方法的第一条语句都是隐含地调用super()如果父类没有这种形式的构造函数那么在编译的时候就会报错public 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和thisthis 和super在构造函数中只能有一个且都必须是构造函数当中的第一行当父类的构造函数是无参构造函数时在子类的构造函数中不用显式super()去调用父类的构造函数,当父类的构造函数是有参构造函数时如果子类的构造函数中不写super()进行调用父类的构造函数编译器会报错java继承后类的初始化顺序静态代码块、非静态代码、父类/子类无参构造方法、父类/子类的一般方法例public 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(叫); } }public 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(喵); } }public 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 修饰的方法不能声明为抽象方法例// 抽象类 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的没有明确指定。public 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关键字来实现一个或多个接口如果一个类实现了某个接口那么它必须实现该接口中的所有抽象方法除了默认方法和静态方法。public class MyClass implements MyInterface { Override public void method() { System.out.println(MyClass的方法); } }例public interface Shape { void draw(); void calculateArea(); }public class Circle implements Shape { Override public void draw() { System.out.println(画圆); } Override public void calculateArea() { System.out.println(计算圆的面积); } }public class Rectangle implements Shape { Override public void draw() { System.out.println(画矩形); } Override public void calculateArea() { System.out.println(计算矩形的面积); } }public 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。public 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); } }注意事项使用instanceof时要确保对象引用变量不是null否则将会抛出NullPointerException。在使用instanceof进行类型判断后如果需要进行类型转换应该使用强制类型转换如(ClassName) obj。尽量避免在代码中过度使用instanceof因为它可能会破坏面向对象的多态性