文章目录
一、初识面向对象
- 面向过程:步骤清晰,每一步做什么;适合简单问题(线性思维)
- 面向对象:分类思维,再对某一分类下的细节进行面向对象的操作;适合复杂及多人协作问题
- 对于复杂事务,宏观上使用面向对象分析整个系统,围观操作时使用面向过程思维处理
- 属性+方法=类
- 对象是通过引用来操作的:栈---->堆(地址)
1.面向对象编程(OOP)
本质:以类的方式组织代码,以对象的方式封装数据
抽象
- 认识论角度:先有对象后有类,对象时具体事物,类是对对象的抽象
- 代码运行角度:先有类后有对象,类是对象的模板
2.三大特征
封装、继承、多态
3.属性
字段Field 成员变量
默认初始化:
数字:0 0.0
char:u0000
boolean:false
引用:null
修饰符 属性类型 属性名 = 属性值
如:人是类,张三是对象,其性别、年龄等静态特征是属性,说话等对象执行的操作是方法
二、类与对象的创建
1.类与对象的关系
- 类是一种抽象的数据类型,是对某一类事物整体描述/定义,但不能代表某一个具体事物
- 类用于描述/定义某一类具体事物应具备的特点和行为
- 对象是抽象概念的具体实例,如张三是人的一个具体实例
2.创建与初始化对象
- 使用new关键字创建对象
- new除了分配内存空间外,还会给创建好的对象进行默认的初始化及对类中构造器的调用
- 类中的构造器也称为构造方法,是在进行创建对象时必须要调用的
- 构造器特点:1.必须和类的名字相同;2.必须没有返回类型,也不能写void
//一个项目应该只存在一个main方法
public class Application {
public static void main(String[] args) {
//类:抽象的,需要实例化
//类实例化后会返回一个自己的对象
//student对象就是一个Student类的具体实例
Student xiaoming = new Student();
Student xiaohong = new Student();
System.out.println(xiaoming.name); //null
xiaoming.name = "小明";
System.out.println(xiaoming.name); //小明
}
}
//学生类
public class Student {
//属性:字段
String name;
int age;
//方法
public void study(){
System.out.println(this.name+"在学习");
}
}
- 一个类即使什么也不写,它也会存在一个方法
三、构造器详解
- 实例化初始值
- 使用new关键字,本质是在调用构造器
- 有参构造:一旦定义有参构造,无参必须显式定义
public class Person {
//一个类即使什么也不写,它也会存在一个方法
String name;
//实例化初始值
public Person(){
this.name = "Ted";
}
}
参考教程:
https://m.php.cn/article/419827.html
四、创建对象内存分析
五、封装
高内聚,低耦合
类的内部数据操作细节不允许外部干涉;
仅暴露少量的方法给外部使用
属性私有,get/set
alt+insert快捷键
package oop.demo3;
public class Student {
//属性私有,外部对象不能直接使用
private String name;//名字
private int id;//学号
private char sex;//性别
//提供一些可以操作这个属性的方法
//public的get、set方法
//get 获得这个数据
public String getName(){
return this.name;
}
//set 给这个数据设置值
public void setName(String name){
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
package oop;
import oop.demo3.Student;
public class Application {
public static void main(String[] args) {
Student s1 = new Student();
s1.getName();
s1.setName("Ted");
System.out.println(s1.getName());
s1.getId();
s1.setId(24);
System.out.println(s1.getId());
}
}
- 提高程序安全性,保护数据
- 隐藏代码的实现细节
- 统一接口
- 提高系统可维护性
六、继承
- 继承的本质是对某一批类的抽象
- 只有单继承
- 继承是类之间的关系(还有依赖、组合、聚和……)
- 子类(派生类)父类(基类)
- 子类继承父类,使用关键字extends表示
- 子类 is a 父类
- private无法被继承
- 先调用父类的无参构造(super();)
- 注:在java中,所有的类都默认继承Object
1.super
- super调用父类的构造方法,必须在构造方法第一个
- 调用父类的构造器,必须在子类构造器的第一行
- super必须只能出现在子类的方法或者构造方法中
- super和this不能同时调用构造方法
super和this的区别:
- this:本身调用这个对象;没有继承也可以使用;本类的构造
- super:代表父类对象的应用;只能在继承条件才能使用;父类的构造
2.方法重写Override
·重写都是方法的重写,与属性无关
·父类的引用指向了子类
·静态方法:方法的调用只和定义的数据类型有关(即左边)
·非静态方法下子类重写了父类的方法,执行子类的方法
- 重写需要有继承关系,子类重写父类的方法:
- 方法名必须相同
- 参数列表必须相同
- 修饰符范围可以扩大但不能缩小:public>protected>default>private
- 抛出的异常范围可以被缩小但不能扩大:ClassNotFoundException --> Exception(大)
重写,子类的方法和父类必须一致,方法体不同 - 为什么需要重写:
父类的功能,子类不一定需要或者不一定满足
七、多态
-动态编译
同一方法可以根据发送对象的不同而采用多种不同的行为方式
- 一个对象的实际类型是确定的,但是可以指向对象的引用的类型很多
- 多态存在的条件:有继承关系、子类重写父类方法、父类引用指向子类对象(Father f1 = new Son()😉
- 注:多态是方法的多态,属性没有多态性
- instanceof :判断一个对象是什么类型,判断两个类是否存在父子关系
Object object = new Student();
object instanceof Student //object指向的实际类是不是Student的子类
(类型转换) 引用类型
//Student类是Person类的子类
//可以指向的引用类型不确定:父类的引用指向子类
Student s1 = new Student();
Person s2 = new Student();
Object s3 = new Student();
- 子类能调用的方法都是自己的或者继承父类的
- 父类可以指向子类,但是不能调用子类独有的方法
- 子类转换为父类,可能丢失自己本来的一些方法
高转低 强制转换:
Person obj = new Student();
//将该对象转换为Student类型,就可以使用Student类型的方法
Student student = (Student) obj;
student.go();
八、static关键字
public class Person{
//2.一般用于赋初始值
{
System.out.println("匿名代码块");
}
//1.只执行一次
static {
System.out.println("静态代码块");
}
public Person(){
System.out.println("构造方法");
}
public static void main(String[] args){
Person person = new Person();
}
/*
输出:
静态代码块
匿名代码块
构造方法
*/
//静态导入包
import static java.Math.random;
· 类前面加final就不能继承
九、抽象类
//abstract 抽象类
public abstract class Action {
//抽象方法,只有方法名字,没有方法实现
public abstract void doSomething();
}
//继承了抽象类的子类,必须实现抽象类的所有方法
public class A extends Action{
public void doSomething() {
}
}
抽象类不能new,只能靠子类去实现
抽象类中可以写普通方法
抽象方法必须在抽象类中
十、接口
- 自己无法写方法,只有规范
- 本质是契约
- 声明接口的关键字:interface
- 接口中所有定义都是抽象的public abstract
- 实现的类需要重写接口中的方法
package oop.demo5;
//interface关键字声明,接口都要有实现类
public interface UserService {
//接口中的属性默认为常量 public static final
//很少在接口中定义常量
int AGE = 99;
//接口中所有定义的方法都是抽象的public abstract
void add(String name);
void delete(String name);
void update(String name);
void query(String name);
}
package oop.demo5;
//类可以实现接口:implements 接口
//实现了接口中的类,就需要重写接口中的方法
public class UserServiceImp1 implements UserService{
@Override
public void add(String name) {
}
@Override
public void delete(String name) {
}
@Override
public void update(String name) {
}
@Override
public void query(String name) {
}
}
- 利用接口实现多继承:public class UserServiceImp1 implements UserService,TimeService{}
- 接口的作用:
- 约束
- 定义了一些方法,让不同人实现
- public abstract
- public static final
- 接口不能被实例化,因为接口中没有构造方法
- implements 可以实现多个接口
- 必须要重写接口中的方法
十一、内部类
- 在一个类的内部再定义一个类
- 内部类可以获得外部类的私有属性和私有方法
- 一个java类中可以有多个class类,但是只能有一个public class
1.成员内部类
- 定义在外部类的成员位置上
- 内部类在外部使用时,需要通过外部类信息才能完成实例化
- 内部类可以直接访问外部类的成员;如果出现同名属性或者方法,优先访问内部类中定义的
- 可以使用 外部类.this.成员 的方式,访问外部类中同名的信息(成员属性和成员方法)
- 外部类访问内部类信息,需要通过内部类实例,无法直接访问
package oop.demo6;
public class Outer {
private int id = 10;
public void out(){
System.out.println("这是外部类方法");
}
public class Inner{
public void in(){
System.out.println("这是内部类方法");
}
//获得外部类的私有属性
public void getID(){
System.out.println(id);
}
}
package oop;
//import oop.demo3.Student;
//import oop.demo4.Student;
import oop.demo6.Outer;
public class Application {
public static void main(String[] args) {
//new
Outer outer = new Outer();
//通过外部类实例化内部类
Outer.Inner inner = outer.new Inner();
inner.in(); //这是内部类方法
inner.getID(); //10
}
}
注:
获取成员内部类对象实例方法:
- 通过外部类对象创建内部类实例,即
new 外部类().new 内部类() 或 外部类对象.new 内部类()
- 通过外部类定义的成员方法获取,即
外部类对象.get方法()
2.静态内部类
- static修饰
- 获取静态内部类对象实例: new 外部类名.静态类();
- 静态内部类中,只能直接访问外部类的静态成员,如果需要调用非静态成员,可以通过对象实例
public class Outer {
private int id = 10;
//定义静态内部类
public static class Inner{
public void in(){
System.out.println("这是内部类方法");
}
//获得外部类的私有属性
public void getID(){
System.out.println(id);
}
public static void main(String[] args) {
//调用静态内部类
Outer.StaticInner staticInner = new StaticInner();
staticInner.getID();
}
}
3.方法内部类(局部内部类)
- 当一个类只需要在某个方法中使用了某个特定的类时使用
- 不能使用任何访问修饰符,不能使用static修饰
- 类中不能包含静态成员,但可以包含final、abstract修饰的成员
public class Outer {
private static int a;
private int b ;
public void partClassTest(final int c){
final int d =1;
//在partCLassTest方法中定义一个局部内部类PastClass
class PastClass{
public void print(){
System.out.println(c);
}
}
}
}
4.匿名内部类
- 没有名字的类
- 通过匿名内部类简化对于抽象类和接口实现的操作
- 不用将实例保存到变量中
参考资料:https://www.jianshu.com/p/79f6d2aca1d8
网课来源
【狂神说JAVA】https://www.kuangstudy.com/