面向对象

面向过程&面向对象
面向过程:线性思维
面向对象:分类思想

-
面向对象编程的本质:以类的方式组织代码,以对象的组织“封装”数据。
-
属性+方法=类
-
认识论:先有对象后有类。对象是具体的事物。类是抽象的,是对对象的抽象,将相似的部分抽象出来。
-
代码运行角度(需要设计,分好类再去实现):先有类后有对象。类是对象的模板。
-
-
-
三大特性:
-
封装:将数据封装起来,只留一个外部访问接口。
-
继承:子类继承父类。
-
多态:同一类事物,因个体不同而有不同的形态
-

回顾方法以及加深

-
break:跳出switch语句、结束循环;
-
continue:跳过一次循环,回到下一次循环
-
return:返回方法的返回值,同时结束方法,方法中、return后,写代码无效
方法回顾

方法调用

-
非静态可以调用静态和非静态
-
非静态可以调用静态和非静态,因为在其中一个被实例化后,两个非静态的会被一起创建,同步加载
-
非静态未实例化前,不占用空间资源

实参与形参

值传递与引用传递
-
值传递:实参与形参在内存上是独立的两个变量
-
引用传递(地址、指针):实参和形参在内存上指向的是同一个地址
-
一个类里边只能有一个public class,但有多个class


类与对象
类与对象的关系
属性+方法=类
-
编程时,先有类,才有对象
-
当方法为static时,该方法与类一起创建,可以直接通过 ”类.方法“ 调用此方法。
-
当方法为非static时,该方法并未初始化,需要先对其所在的类进行实例化,返回该类的一个对象(可以返回多个),才会被分配空间而创建从而真实存在(之前只是定义)。
-
对象:实例化后的类返回的
-
非static方法,在对应的类实例化为返回对象后,通过 “对象.方法0” 进行调用。
-
对于对象,也可以使用 “对象.属性” 去对属性进行操作。
-
-

-
以类的方式组织代码,以对象的形式封装具体的数据

构造器

一个类即使什么都不写,也会存在一个构造方法

-
创建构造器,快捷键:alt+insert(insert与其他键复用时,需要按住fn或者shift去选中)
-
选择Select None,会创建无参构造器
-
前边写好属性后,构造时按住shift,可以多选参数,点击OK,则会创建重载的有参构造器
-

-
有参构造器:一旦定义了有参构造,无参就必须显式定义,否则无效
-
无参构造器
-
类进行实例化的过程:需要先进入构造器,构造器走完,才会生成对象。
-
实例化:要调用类中的非static变量或者方法,就必须先对类进行实例化为对象,采用 “对象.方法” 或 “对象.变量” 的方式调用。
-
作用
-
对实例化的值进行初始化
-
使用new关键字,本质是在调用构造器
-
-



创建对象内存分析
栈用于存放变量与执行方法,堆用于加载方法与数据
步骤
-
step1:构建Application类与静态方法区
-
step2:进入main方法
-
step3:构建Pet类
-
step4:进行默认地无参构造,并给Pet类中参数初始化
PS:类进行实例化的过程:需要先进入构造器,构造器走完,才会生成对象。
-
step5:创建引用变量cat与dog,引用变量指向的地址内存
-
step6:继续执行main方法
-
step:根据main方法中的变量值与方法,对Pet类中数据进行赋值与方法执行


总结
-
类与对象
-
类是一个模板:抽象;对象是一个具体的实例
-
-
方法
-
定义、调用
-
-
对应的引用
-
引用类型:对象是通过引用来操作的:栈--->堆(地址)
-
基本类型(8):int、long、short、boolean、double、float、byte、char。
-
-
属性:字段Field 成员变量
-
默认初始化:
-
数字:0、0.0
-
char : u0000
-
boolean : false
-
引用:null
-
-
修饰符 属性类型 属性名 = 属性值!
-
-
对象的创建与使用
-
必须使用new关键字创建对象,构造器 Person kuangshen = new Person();
-
对象的属性 kuangshen.name
-
对象的方法 kuangshen.sleep();
-
-
类:
-
静态的属性 属性
-
动态的行为 方法
-
三大特性

封装
-
程序设计要追求:高内聚低耦合
-
高内聚就是类的内部数据操作细节自己完成,不允许外部干涉
-
低耦合:仅暴露少量的方法给外部使用。
-
属性私有,get/set
-

-
快捷键:alt+insert,快速设置set与get方法



继承

最终程序



-
快捷键:ctrl+H,显示父子关系
-
私有(private)的东西,无法被继承
在main中子类使用父类东西--单独程序



-
在main中子类使用父类东西,需要将子类实例化,父类会在子类构造器中自动完成实例化,之后可以直接使用

-
-
子类与父类东西不同,直接调用
-

-
-
子类与父类东西(属性与方法)相同,就近调用
-

object类
在java中,所有的类,都默认直接或者简介继承object类
supper,对比this:在子类中调用父类东西
-
子类实例化,父类会自动实例化
-
写有参构造时,需要把无参构造显式地写出来,避免子类调用父类无参/有参出错
-
程序最开始走到new类实例化时,就对子类与父类进行了初始化,而且是父类在前,子类在后
![1649234061186]()
-
隐藏了代码——super();:子类的无参构造中调用了父类的无参构造,且显示写出super();时,必须写在第一行,否则报错
![1649234429377]()
-
子类无参会默认调用父类无参,但如果父类是有参构造,子类也必须显式地写出调用父类的有参构造。
-
子类中super和this不能同时调用构造方法!因为都需要在第一行。
-
-
在子类中调用父类的东西,用super

总结
-
final修饰的类,无法被继承
-
super注意点:
-
子类用super调用父类的构造方法,必须在构造方法的第一个。
-
super必须也只能出现在子类的方法或者构造方法中。
-
子类中super和this不能同时调用构造方法!因为都需要在第一行。
-
-
VS this
-
代表的对象不同:
-
this:本身调用者这个对象
-
super:代表父类对象的应用3
-
-
前提:
-
this:没有继承也可以使用
-
super:只能在继承条件才可以使用
-
-
构造方法
-
this():本类的构造
-
super():父类的构造
-
-
方法的重写
非static:会被重写,并且就近调用
-
当子类方法名与父类方法名相同、且都为非static时,需要加入重写注解,进行方法重写

-
快捷键,alt+insert可以直接重写方法,默认继承父类,但可以自己修改


-
非static会被重写,并且就近调用,输出结果相同。

static:不能被重写,但是能够被再次声明。
-
父类的引用转向了子类,new A()--子类的时候,会自动new B()--父类,B b说明此处实例化后的对象b属于B;
-
但反之A c = new B();不行,因为new父类的时候,子类并未被实例化

-
static不能被重写,通过不同的实例化调用,因为无法实例化为对象,本质还是类,输出的结果不同,不执行就近原则

非静态与静态区别很大:
-
B b = new A();中,b是A new出来的对象,因此 b.test() 调用了A的方法。
-
因为静态方法是类的方法,而非静态是对象的方法。
-
有static时,方法可以直接通过 “类.方法” 调用,B类无需实例化(可以实例化为对象,但静态的不会走对 象.方法 的调用),b需要从B类去调用, b.test() 等价于B.test() ,b调用了B类的方法,因为b是用b类定义的。

-
非static时,方法需要通过 “对象.方法” 去调用,B类需要被实例化为一个对象,b.test() 等价于new A().test(),b调用的是对象的方法,而b是用A类new出来的。B b = new A();子类重写了父类的方法。

总结
-
重写:需要有继承关系,子类重写父类的方法!
-
方法名必须相同
-
参数列表必须相同
-
修饰符:范围可以扩大,但不能缩小。public>protected>default>private
-
抛出的异常:范围可以缩小,但不能扩大。ClassNotFoundException---->Exception(大)
-
-
重写,子类的方法要和父类一致;方法体不同!
-
为什么需要重写:
-
父类的功能,子类不一定需要,或者不一定满足!
-
alt+insert:override;
-
实时检测功能的问题:
-
实时检测功能是开发规约插件的功能,根据公约不应该用类实例变量访问静态成员,所以报错
-
但关闭实时检测后,不再报错
-
不关闭,即使此处报错,也可以执行
-
此处更新一个结论:静态成员变量,可以直接通过 类.方法 访问。也可以通过实例变量的方式进行访问,但不应该。


多态:重写---->多态

代码



父类与子类的多态
-
一个对象的实际类型时确定的;但可以指向这个对象的引用类型就不确定了,父类的引用指向子类。

-
对象能执行哪些方法,主要看对象左边的类型,和右边关系不大
![1649256319226]()
-
对s1,左边是student(子类),则要看子类有没有对应的函数:
-
若有则直接执行自己的
有test,则test执行自己的
![1649256596785]()
-
若没有的看能否继承父类。
无eat,但继承自父类
![1649256635154]()
-
对s2,左边为person(父类),则看父类有没有对应函数
-
eat未被子类重写,则执行自己的
![1649256739047]()
-
run被子类重写,则执行子类的
![1649256771564]()
-
父类无法调用子类,会被强制转换
![1649256828215]()
-
-
多态注意事项
-
多态是方法的多态,属性没有多态
-
父类和子类,有联系 若无联系,会类型转换异常! ClassCastException
-
存在条件
-
继承关系
-
方法需要重写
-
不可重写的
-
static 方法,属于类,它不属于实例
-
final 常量
-
private 方法;
-
-
-
父类的引用指向的是子类对象! father f1 = new son();
-
instcanof与类型转换
instanceof
-
instanceof可以判断是否有父子关系。

-
System.out.println(X instanceof Y);
-
能不能通过编译,看X与Y是否在一条族谱线
-
instanceof结果是true或者false,看是否有父子关系,并遵循向上转型
-


类型转换
-
高转低,强制转换,父类调用子类的东西,强制转换后可以使用
-
低转高,自动转换,但可能会丢失一些自己本来的方法!



总结
-
总结:
-
父类的引用指向子类的对象。
-
把子类转换为父类,低转高,向上转型;可能会丢失子类本身的一些方法。
-
把父类转化为子类,高转低,向下转型,需要强制转换。
-
方便方法的调用,减少重复的代码!简洁
-
-
抽象:封装、继承、多态! 抽象类,接口。
static
静态变量与非静态变量
-
静态变量,可以直接用过类的形式在其他类调用,多用于需要多处类使用的变量;
-
静态变量,用 类.对象 的形式调用,输入Student会默认显示age;但用实例变量形式,虽不会错,但输入s1不会会默认显示age;
-
静态变量,不论是否实例化,都是属于类的,应采用类的形式去调用;
-
非静态变量,必须对类进行实例化,采用 对象.变量 调用

静态方法与非静态方法
-
静态方法可以直接调用,也可以用 类.方法 调用
-
非静态方法,必须对类进行实例化,采用 对象.方法 调用
-
静态方法只能调用静态方法,非静态方法可以调用静态、非静态方法。
静态代码块
-
1 静态代码块,Person类加载时执行,永久只执行一次
-
2 匿名代码块:在构造器之前、实例化对象时加载;可以用于赋初值,但程序无法直接调用该匿名代码块。
-
3 构造方法,实例化对象时加载

静态导入包
-
导入对应类的包后,可以直接调用里边的函数

抽象类--单继承



抽象方法
-
abstract,约束~有人帮我们实现~抽象方法,只有方法名字,没有方法的实现!
抽象类
-
abstract 抽象类:本质是类,需要继承extends 单继承~;接口可以多继承。
-
继承了抽象类的子类,都必须要实现(重写)父类抽象类的所有方法~除非子类也是抽象类
-
特点:抽象的抽象——就是一个约束
-
不能new这个抽象类,只能考子类去实现它;约束!
-
抽象类可以写普通的方法与抽象的方法
-
但抽象的方法必须写在抽象类中
-
-
思考题
-
不能new,存在构造吗?----------存在,alt+insert可以直接写出来
-
存在的意义?---------------抽象出来,提高开发效率,可扩展性更强
-
接口--多继承
Interface

-
Java单继承,但通过接口来实现“伪多继承”

-
接口
-
interface 定义的关键字 接口都需要有实现类,重写其中的所有方法
-
实现了接口的类,就需要重写接口中的所有方法~
-
格式:类 可以实现接口 implements 接口
-
![1649335090763]()
-
接口中所有东西都是抽象的
-
如果不写修饰符,属性默认为常量~ 但一般不会在接口中定义常量
-
如果不写修饰符,方法默认是public abstract;可以只写返回值类型、方法名、参数类型、形参
-
-



作用
-
约束
-
定义一些方法,让不同的人实现~
-
方法都是public abstract
-
属性都是public abstract final
-
接口不能被实例化,接口中没有构造方法
-
implements可以实现多个接口
-
实现接口的类,必须重写接口的方法
内部类

1、成员内部类:外部类的内部类
-
内部类可以通过新建一个方法,在方法体内获得外部类的私有属性、方法
-
但无法在外部直接使用,会报错

-
内部类的实例化:通过外部类实例化后的对象去进行实例化

2、静态内部类
-
static在类加载时一起加载,此时还不存在外部类的属性,所以无法获取id与方法out()。

-
且静态的类无法调用非静态的方法,静态只能调用静态

外部类的内部类与一个java类中的内部类不同
-
一个java类中可以有多个classs类,但只能有一个public class类

3、局部内部类:方法中的内部类

-
没有名字初始化类,不用将实例保存到变量中~

4、匿名内部类,接口相关:
-
接口没法new,new的话实际是在创建一个实现它的匿名内部类,并重写方法
-
实际会返回UserService userService = new UserService() {...}









浙公网安备 33010602011771号