20240319_Objected_Oriented_Programming
参考来源:狂神说java
测试的main方法
package OOP;
public class OOP {
/*面向对象编程:Object-Oriented Programming
本质:以类的方式组织代码,以对象的方式封装数据
三种特性:封装、继承、多态
*/
public static void main(String[] args) {
Student student = new Student();//Student对象的实例化
student.study();
student.age = 24;
student.name = "老八";
student.howOld();
student.whatName();
System.out.println("============");
//在类存在有参构造之后如果要调用无参,必须手动显式构造
Person person1 = new Person();
System.out.println(person1.name + "\t" + person1.age);//null 0
Person person2 = new Person(10, "kui");
System.out.println(person2.age +"\t" + person2.name);//10 kui
System.out.println("============");
//封装:
System.out.println(person1.setId(666));
System.out.println(person2.setPhoneNumber(999));
System.out.println(person2.getName());
System.out.println("============");
//继承:
NewMan person3 = new NewMan();
System.out.println(person3.name = "hui");
System.out.println(person3.setId(111));
person3.setId(666);
System.out.println("============");
//父类方法的调用
person3.test();
System.out.println("============");
//无参构造的调用顺序:先父类再子类:
NewMan person4 = new NewMan();
//Person无参被执行了
//NewMan无参被执行了
//说明子类构造的时候先调用父类构造器
System.out.println("============");
//方法的重写,override:加static之后便无缘重写
NewMan a = new NewMan();
Person b = new NewMan();
//加static AB
a.B();
b.B();//是什么类就调用什么类的静态方法
//不加:AA,子类的方法重写了父类的方法,
// 双方都只能是public修饰
System.out.println("============");
//多态:同一行为发生在不同对象产生不同效果
//存在条件:继承关系、子类重写父类方法、父类引用指向子类对象
//变量名前是引用类型,new后是实际类型
NewMan man1 = new NewMan();
//NewMan s4 = new Person();报错
Person man2 = new NewMan();
//向上转型,父类引用指向子类,他是个newman但是是person类
Person man3 = new Person();
man1.eat();//吃饭
man2.eat();//吃饭,子类重写父类方法,调用子类的
man3.eat();//吃面
man1.festival();
//s2.festival();报错,要将父类强制转换成子类如下:
((NewMan)man2).festival();
//向下转型,高转低,要强制转换,只有向上转型过的对象才能向下转型
System.out.println("============");
//instanceof关键词:判断一个对象和某个类之间是否存在父子关系
System.out.println(man1 instanceof NewMan);//true
System.out.println(man1 instanceof Person);//true
System.out.println(man1 instanceof Object);//true
//System.out.println(s1 instanceof Student);报错
System.out.println("============");
System.out.println(man2 instanceof NewMan);//true
System.out.println(man2 instanceof Person);//true
System.out.println(man2 instanceof Object);//true
System.out.println("============");
System.out.println(man3 instanceof NewMan);//false,Person不是NewMan子类
System.out.println(man3 instanceof Person);//true
System.out.println(man3 instanceof Object);//true
//看new后面的类是否和instanceof后面的有父子关系,或同级关系
System.out.println("============");
}
}
父类:Person
package OOP;
public class Person {
/*
构造器:有参构造器和无参构造器,使用new关键字本质就是调用构造器
一个类什么都不写也存在一个和类名一样的方法,称为构造器,无返回值
区别为有无参数传入
*/
int age;
String name;
//这是一个无参构造器
public Person() {
System.out.println("Person无参被执行了");
}
//alt + insert快捷生成
public Person(int age, String name) {//这是一个有参构造器
this.age = age;
this.name = name;
}
//声明私有属性:这样在main方法里无法直接修改属性,体现封装特性
private int id;//身份证号
private int phoneNumber;//手机号码
//这样在main方法里无法直接修改属性,
// 所以要定义一些get/set这个属性的方法供调整:
//用set设置
public int setId(int a) {
return this.id = a;
}
public int setPhoneNumber(int a) {
return this.phoneNumber = a;
}
//用get获取
public String getName(){
return this.name;
}
public void print(){
System.out.println("kui");
}
public static void B(){
System.out.println("B");
}
public void eat(){
System.out.println("吃面");
}
}
Student类
package OOP;
public class Student {//声明一个学生类
int age;
String name;
//声明方法:
public void study(){
System.out.println("i m studying...");
}
public void sleep(){
System.out.println("Zzzzzzzzzz...");
}
public void howOld(){
System.out.println(this.age + " years old.");
}
public void whatName(){
System.out.println("My name is: " + this.name);
}
}
Person子类NewMan
package OOP;
public class NewMan extends Person{//继承的关键字:extends
//private不能被继承
public NewMan(){
super();
/*这是隐藏的,
调用父类构造器必须在子类的第一行,
父类没有无参构造,
子类也无法无参构造
只能调用无参构造
*/
System.out.println("NewMan无参被执行了");
}
@Override//重写
public void print() {
System.out.println(this.name = "KUI");
}
public void test(){
print();
this.print();
super.print();//调用父类方法,若父类用private则不行
}
//@Override//注解:有功能的注释
public static void B() {
System.out.println("A");
}
@Override
public void eat() {
System.out.println("吃饭");
}
//子类独有的方法
public void festival(){
System.out.println("过端午");
}
}
构造代码块
package StaticPractise;
public class Person {//用final修饰则不能被继承
{//(匿名)代码块
System.out.println("代码块");
}
static {//静态代码块,只执行一次
System.out.println("静态代码块");
}
public Person() {
System.out.println("构造方法");
}
public static void main(String[] args) {
Person person1 = new Person();//静态->代码块->构造方法
System.out.println("==================");
Person person2 = new Person();//代码块->构造方法
}
}
- {……}括起来的称为代码块或代码段
- 只有{……}括起来的称为构造代码块
- 构造代码块和构造方法一样都时被实例化的时候被调用
- 构造代码块比构造方法先行
- 类每次实例化都要调用构造代码块
- static修饰的构造代码块称为静态代码块
- 类加载的时候执行静态代码块,类实例化时执行构造代码块
总结
-
面向对象编程本质:以类的方式组织代码,以对象的方式封装数据
-
OOP的三大特征:封装、继承、多态
-
构造器(构造方法):分为有参构造和无参构造,一个类中可以有多个构造器,但是参数列表不能相同,即方法的重载,作用为给实例化对象,给对象赋初始值。可以调用本类的构造方法用this(),也可以调用父类的构造方法super(),但是两者必须是构造器里的第一行,故不可同时出现
-
封装:信息隐藏,使用private关键字封闭类,private修饰的数据表示私有,只能在本类中访问,留下必要的set/get方法接口供给与外部发生联系,此时set/get方法不能用static关键字修饰,称为实例方法。
总而言之,Java中的封装包含下列步骤:需要被保护的属性用private修饰,针对此属性开放getset接口供给调整。
-
继承:封装之后类成为独立体,独立体之间可能存在继承关系,声明时用关键字 extends + 父类名 表示继承父类属性,但是父类带private的属性值不能被继承,继承解决了代码复用的繁杂。子类和父类代码块执行顺序:父类静态代码块—》子类静态代码块—》父类代码块—》父类构造方法—》子类代码块—》子类构造方法。
总结:静态最先,父类优先于子类,代码块优先于构造方法
-
方法重写(Override)与多态:区别于方法的重载(同一类中方法名相同,参数类型、个数、顺序不同便构成方法的重载),当父类继承的方法无法满足需求时,子类便会重写父类的方法。重写是将继承父类的方法进行覆盖。首要条件是必须发生在父类和子类之间,且覆盖后的方法与原方法具有相同的返回值类型、相同方法名,相同参数名称列表,static修饰的静态方法无缘重写。
只有当封装的独立体并且独立体之间有继承关系之后才有多态机制。简而言之,多态就是同一行为发生在不同对象上有不同效果。多态存在的条件:继承关系,子类重写父类方法,且实例化时父类引用指向子类对象(Person AMan = new Man())。父类引用指向子类对象也叫向上转型,此时AMan是一个Man对象,但是属于Person类,因为是“低辈分”转“高辈分”所以是合法的声明,如果是Man AMan = new Person()则直接报错。当向上转型的子类调用override的方法时调用的时子类的重写过的方法。父类的对象无法调用子类独有的方法,若要调用需要强制类型转换,((低辈分)高辈分的对象名).低辈分独有的方法 方可,此时也叫向下转型,只有向上转型过的对象才能向下转型。
-
instanceof关键字:用于判断左边的对象是否是右边的类或其子类的实例化,Person student = new Student():指的是Student的实例化,但是属于Person类。