| 就是模板,⽤来定义⼀类对象的⽅法和属性,⽐如⼈、学⽣、猫,万物都是有模板,都是可以定义为类。 (类名⾸字⺟⼤写) |
| 类的实例化,⽐如 学⽣这个类实例化,就是 XX同学 |
| |
| # 如下 |
| Student student = new Student(); |
| Cat cat1 = new Cat(); |
| new Persion(); |
| ⽅法是语句的集合,在⼀起完成⼀个功能 |
| ⽅法包含于类或对象中,即普通⽅法或者类⽅法 |
| ⼦类继承⽗类的特征和⾏为,使得⼦类对象具有⽗类的⽅法和属性 |
| ⽗类也叫基类,具有公共的⽅法和属性 |
| |
| 格式,通过extends关键字 |
| class ⽗类名称{ |
| |
| } |
| |
| class ⼦类名称 extends ⽗类名称{ |
| |
| } |
| |
| ⼦类拥有⽗类的⾮private的属性和⽅法 |
| ⼦类可以⽤⾃⼰的⽅式实现⽗类的⽅法 override(重写,覆盖) |
| 实现了代码的复⽤ |
| 重写从⽗类那⾥继承来的⽅法的,当调⽤⽅法时候会优先调⽤⼦类的⽅法(默认就近原则) |
| |
| 不⽀持多继承,⽀持多重继承,多重继承提⾼了耦合性,组合优于继承 |
| 所有的类都是继承于 java.lang.Object |
| final关键字 |
| 修饰的类,则这个类不可以被继承 |
| 修饰⽅法,则这个⽅法不允许被覆盖(重写) |
| 同⼀个⾏为具有多个不同表现形式的能⼒ |
| 优点:减少耦合、灵活可拓展 |
| ⼀般是继承类或者重写⽅法实现 |
| 关键词abstract声明的类叫作抽象类,abstract声明的⽅法叫抽象⽅法 |
| ⼀个类⾥包含了⼀个或多个抽象⽅法,类就必须指定成抽象类 |
| 抽象⽅法属于⼀种特殊⽅法,只含有⼀个声明,没有⽅法体 |
| |
| 当⽗类的某些⽅法不确定时,可以⽤abstract关键字来修饰该⽅法,即抽象⽅法,⽤abstract来修饰该类,即抽象类 |
| 抽象类将事物的共性的东⻄提取出来,由⼦类继承去实现,代码易扩展、易维护 |
| |
| # 格式 |
| |
| abstract class 类名{ |
| } |
| |
| |
| abstract 返回类型 ⽅法名(); |
| |
| # 如下 |
| public abstract class Vehicle { |
| |
| public abstract void run(); |
| |
| public void stop(){ |
| System.out.println("停在路上"); |
| } |
| } |
| |
| class Bicycle extends Vehicle{ |
| |
| @Override |
| public void run() { |
| System.out.println("⼈⼯驱动"); |
| } |
| } |
| |
| class Automobile extends Vehicle{ |
| |
| @Override |
| public void run() { |
| System.out.println("汽油驱动"); |
| } |
| } |
| 抽象类不能被实例化,因为抽象类中⽅法未具体化,这是⼀种不完整的类,所以不能直接实例化,编译⽆法通过 |
| 抽象类中不⼀定包含抽象⽅法,但是有抽象⽅法的类必定是抽象类 |
| 如果⼀个抽象类中可以没有抽象⽅法,这样做的⽬的是为了此类不能被实例化。 |
| 抽象类的⼦类必须给出抽象类中的抽象⽅法的具体实现,否则⼦类也是抽象类,需要⽤abstract声明 |
| 抽象类不能使⽤final关键字修饰,因为final修饰的类是⽆法被继承 |
| 抽象类中的抽象⽅法只是声明,不包含⽅法体 |
| 抽象⽅法不能⽤private修饰,因为抽象⽅法必须被⼦类实现(覆写),⽽private权限对于⼦类来 说是不能访问的 |
| ⼀个类继承了⼀个抽象类,那么它必须全部覆写抽象类中的抽象⽅法,当然也可以不全部覆写,如果 不覆写全部抽象⽅法则这个⼦类也必须是抽象类 |
| |
| 构造⽅法,类⽅法(即static 修饰的⽅法)不能声明为抽象⽅法 |
| 是抽象⽅法的集合,接⼝通常以interface来声明,⼀个类通过继承接⼝的⽅式,从⽽来继承接⼝的抽象⽅法 |
| |
| interface 名称 [extends 其他的接⼝名] { |
| |
| |
| int getMoney(); |
| } |
| * 接⼝的⽅法都是抽象⽅法,默认都是 public abstract,其他修饰符都会报错 |
| * 接⼝中可以含有变量,但是接⼝中的变量会被隐式的指定为 **public static final** |
| * 类描述对象的属性和⽅法,⽽接⼝则包含类要实现的⽅法 |
| * 接⼝⽆法被实例化,需要被实现才⾏ |
| * ⼀个实现接⼝的类,必须实现接⼝内所描述的所有⽅法,否则就必须声明为抽象类 |
| * 接⼝没有构造函数 |
| * 接⼝⾥可以有静态⽅法和⽅法体 |
| * 接⼝中所有的⽅法必须是抽象⽅法(JDK8之后就不是) |
| * 接⼝不是被类继承了,⽽是要被类实现 |
| * 接⼝⽀持多继承, 类不⽀持多个类继承 |
| 当类实现接⼝的时候,类要实现接⼝中所有的⽅法,不然类必须声明为抽象的类,使⽤implements关键字实现所有接⼝ |
| |
| class 类名 implements 接⼝名称[其他接⼝名称, 其他接⼝名称]{ |
| |
| } |
| ⼀个类只能继承⼀个类,但是能实现多个接⼝ |
| 接⼝能继承另⼀个接⼝,接⼝的继承使⽤extends关键字,和类继承⼀样 |
| interface中可以有static⽅法,但必须有⽅法实现体,该⽅法只属于该接⼝,接⼝名直接调⽤该⽅法 |
| 接⼝中新增default关键字修饰的⽅法,default⽅法只能定义在接⼝中,可以在⼦类或⼦接⼝中被重写,default定义的⽅法必须有⽅法体 |
| ⽗接⼝的default⽅法如果在⼦接⼝或⼦类被重写,那么⼦接⼝实现对象、⼦类对象,调⽤该⽅法,以重写为准 |
| 本类、接⼝如果没有重写⽗类(即接⼝)的default⽅法,则在调⽤default⽅法时,使⽤⽗类定义的default⽅法逻辑 |
| ⼀种特殊的⽅法 |
| 创建对象时⽤来初始化对象,每次使⽤new 创建对象的时候,就会使⽤构造函数 |
| 与类具有相同的名称,但是没有返回值 |
| Java会⾃动为每个类提供⼀个默认构造函数 |
| 如果⾃⼰定义了构造函数,就不再使⽤默认构造函数,如果没有显示的写出默认构造函数,则会消失 |
| |
| 如果构造函数之间互相调⽤,务必写在⽅法第⼀⾏ |
| 默认构造函数 |
| public 类名(){ |
| } |
| |
| ⽆参构造函数 |
| public 类名(){ |
| |
| } |
| |
| 有参构造函数 |
| public 类名(参数类型1 参数名1,参数类型2 参数名2...){ |
| |
| } |
| public ⽤的最多,⽤来创建对象 |
| private 私有化构造函数,不给外部创建对象,⽐如⼯具类,或者单例设计模式 |
| default 默认的话,只能在当前包⾥⾯使⽤new 创建对象,⼏乎不⽤ |
| 在⼀个类⾥⾯,⽅法名字相同,⽽参数不同,和返回类型⽆关 |
| |
| |
| |
| 注意点: |
| 返回值和形参都不能改变 |
| ⽗类的成员⽅法只能被它的⼦类重写 |
| final 和 static的⽅法不能被重写 |
| 构造⽅法不能被重写 |
| 访问权限不能⽐⽗类中被重写的⽅法的访问权限更低 |
| override是在不同类之间的⾏为,overload是在同⼀个类中的⾏为 |
| # 当⼀个对象创建后,JVM会给这个对象分配⼀个引⽤⾃身的指针,这个指针的名字就是 this |
| # 只能⽤于⾮静态⽅法体内,静态⽅法和代码块不能出现this |
| # this就是指向当前对象本身 |
| |
| # 使用场景 |
| this(参数类型1 参数名,...) 表示当前类对应的构造函数 |
| ⽅法形参和对象的属性重名,⽤this来区分 |
| |
| # 如下 |
| public void setAge(int age){ |
| this.age = age; |
| } |
| ⼀个引⽤变量,⽤于引⽤⽗类对象 |
| ⽗类和⼦类都具有相同的命名⽅法,要调⽤⽗类⽅法时使⽤ |
| ⽗类和⼦类都具有相同的命名属性,要调⽤⽗类中的属性时使⽤ |
| super也是⽗类的构造函数,格式 super(参数) |
| 注意点: 调⽤super() 必须是类构造函数中的第⼀条语句,否则编译不通过 |
| 每个⼦类构造⽅法的第⼀条语句,都是隐含地调⽤super(),如果⽗类没有这种形式的构造函数,那么在编译的时候就会报错 |
| |
| # 如下父类中编写无参构造器 |
| public class Father { |
| public Father(){ |
| System.out.println("father ⽆参构造函数"); |
| } |
| } |
| # 子类重写父类时,构造器中会使用super方法调用父类的无参构造器 |
| public class Children extends Father{ |
| public Children(){ |
| |
| super(); |
| System.out.println("Child⽆参构造函数"); |
| } |
| } |
| |
| this()和super()都指的是对象,均不可以在static环境中使⽤包括:static变量,static⽅法,static语句块 |
| this 和super在构造函数中只能有⼀个,且都必须是构造函数当中的第⼀⾏ |
| 当⽗类的构造函数是⽆参构造函数时,在⼦类的构造函数中,不⽤显式super()去调⽤⽗类的构造函数, |
| 当⽗类的构造函数是有参构造函数时,如果⼦类的构造函数中不写super()进⾏调⽤⽗类的构造函数,编译器会报错 |
| # 父类 |
| public class Father { |
| |
| static { |
| System.out.println("⽗类静态代码块"); |
| } |
| |
| public Father(){ |
| System.out.println("father ⽆参构造函数"); |
| } |
| |
| public Father(int age){ |
| System.out.println("father 有参构造函数"); |
| } |
| |
| public void sleep(){ |
| System.out.println("father sleep⽅法"); |
| } |
| } |
| |
| # 子类继承父类 |
| public class Children extends Father{ |
| static { |
| System.out.println("Child静态代码块"); |
| } |
| public Children(){ |
| |
| System.out.println("Child⽆参构造函数"); |
| super.sleep(); |
| } |
| public void sleep(){ |
| System.out.println("Child sleep⽅法"); |
| } |
| } |
| |
| # main方法测试 |
| public static void main(String[] args) { |
| new Children().sleep(); |
| } |
| |
| # 静态代码块、⾮静态代码、⽗类/⼦类⽆参构造⽅法、⽗类/⼦类的⼀般⽅法 |
| 是Java的⼀个⼆元操作符(运算符),也是Java的保留关键字 |
| 判断⼀个类是否实现了某个接⼝,或者判断⼀个实例对象是否属于⼀个类 |
| |
| # 如下:如果该object 是该class的⼀个实例,那么返回true。如果该object 不是该class的⼀个实例,或者object是null,则返回false |
| boolean result = object instanceof class |
| |
| # 如下:对象类型强制转换前的判断 |
| Person p1 = new Student(); |
| |
| if(1p instanceof Student) |
| { |
| |
| Student s = (Student)p1; |
| } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 字符编码:从基础到乱码解决
· 提示词工程——AI应用必不可少的技术