java面向对象
面向过程开发:
其实就是面向具体的每一个步骤和过程,把每一个步骤和过程完成,然后有这些功能方法相互调用,完成需求
代表语言:C语言
面向对象是基于面向过程的编程思想
面向过程:强调的是每一个功能的步骤
面向对象:强调的是对象,然后由对象去调用功能
面向对象的特点:
1:是一种更符合我们思想习惯的思想
2:可以将复杂问题简单化
3:将我们从执行者变成指挥者
举例:
买电脑:
面向过程: 了解电脑
了解需求
对应参数信息
去电脑城买电脑
讨价还价
买回电脑
面向对象:
我要买电脑,叫人去给我买 ,别人给我买回来
洗衣服:
面向过程:脱衣服 找洗衣盆 放洗衣粉 加点水 戳衣服 清洗衣服 拧干 晾衣服
面向对象:脱衣服 打开洗衣机 扔衣服 一键即可 晾起来
面向对象开发:
就是不断的创建对象,使用对象,指挥对象做事情
面向对象设计:
其实就是在管理与维护对象之间的关系
面向对象特征:
封装
继承
多态
现实世界如何描述一个事物:
学生
姓名,性别 年龄
学习 吃饭 水蕨
属性:该事物的信息
行为:该事物能够做什么
学习编程语言,是为了模拟现实世界的事物的
java中最基本的单位是:类
将事物用类体现出来
事物和类的对应关系:
事物: 类:
属性 成员变量
行为 成员方法
类:是一组相关的属性和行为的集合。是一个抽象的概念
对象:是该类事物的具体表现形式。具体存在的个体
举例;
学生:类
班长:对象
定义类:其实对应类就是定义类的成员变量与成员方法
如何使用:
创建对象使用
如何创建:
格式:类名 对象名 = new 类名()
如何使用成员变量:
对象名.变量名
如何使用成员方法:
对象名.方法名(参数)
成员变量与成员变量的区别:
1:在类中的的位置不同
成员变量:在类中方法外
局部变量:在方法定义中或者方法声明
2:在内存中的位置不同
成员变量:堆内存
局部变量:栈内存
3:生命周期不同
成员变量:随着对象的创建而存在,随着对象的消失而消失
局部变量:随着方法的调用而存在,随着方法的调用完毕而消失
4:初始化值不同:
成员变量:有默认初始化值
局部变量:没有默认初始化值,必须定义,赋值,然后才能使用
注意:
局部变量名称可以和成员变量名称一样,在方法中使用的时候,采用的是就近原则。
形式参数问题:
基本类型:形式参数的改变不影响实际参数
引用类型:形式参数的改变直接影响实际参数
类和数组是引用类型
匿名对象:
就是没有名字的对象
new Student();
匿名对象的应用场景:
1:调用方法:仅仅调用一次时候
调用多次时不适合
匿名对象好处:
匿名对象调用完就是垃圾,可以被垃圾回收器回收
匿名对象调用方法:
new Student().show();
2:匿名对象可以作为实际参数传递
测试类一般只创建对象,调用方法
数据判断不可以在成员变量位置,因为做数据校验,必须依靠逻辑语句,逻辑语句应该定义在方法中
封装:是指隐藏对象的属性和实现细节,仅对外提供公共访问方式
好处:
隐藏实现细节,提供公共的访问方式
提高了代码的复用性
提高安全性
封装原则:
将不需要对外提高的内容都隐藏起来
把属性隐藏,提供公共方法对其访问
private关键字:
是一个权限修饰符
可以修饰成员(成员变量和成员方法)
被private修饰的成员只能在本类中才能访问
private的应用:
把成员变量用private修饰
提供对应的getXxx()和setXxx()方法
this关键字:
代表所在类的对象引用
方法被哪个对象调用,this就代表那个对象
什么时候使用this
局部变量隐藏成员变量
构造方法作用:
给对象的数据进行初始化
构造方法格式:
方法名与类名相同
没有返回值类型,连void都没有
没有具体的返回值
注意事项:
如果你不提供构造方法,系统会给出默认构造方法
如果你提供了构造方法,系统将不再提供
构造方法也是可以重载的
给成员变量赋值:
1:setXxx()
2:构造方法
类的组成:
成员变量
构造方法
成员方法
方法具体划分:
根据返回值:
有明确返回值的方法
返回void类型的方法
根据形式参数:
无参方法
带参方法
一个基本类的标准代码写法:
类:
成员变量
构造方法
无参构造方法
带参构造方法
成员方法:
getXxx()
setXxx()
给成员变量赋值的方式:
无参构造方法+setXxx()
带参构造方法
static关键字:可以修饰成员变量,也可以修饰成员方法
特点:
1;随着类的加载而加载
回想main方法
2:优先于对象存在
3:被类的所有对象共享
4:可以通过类名调用(推荐使用)
其实它本身也可以通过对象名调用
静态修饰的内容议案称其为:与类相关的,类成员
注意事项:
1:在静态方法中没有this关键字的
静态是随着类的加载为加载,this是随着对象的创建而存在
静态比对象先存在
2:静态方法只能方法访问静态的成员变量和静态成员方法
静态方法:
成员变量:只能访问静态变量
成员方法:只能方法静态成员方法
非静态方法:
成员变量:可以是静态的木叶可以非静态的
成员方法:可以是静态的成员方法,也可以是非静态的成员方法
静态变量和成员的区别:
所属不同
静态变量属于类,也称为类变量
成员变量属于对象,也称为实例变量
内存中的位置不同:
静态变量存储于方法区的静态区
成员变量存储于堆内存
内存出现时间不同:
静态变量随着类的加载而加载,随类的消失而消失
成员变量随着对象的创而存在,随着对象的消失而消失
调用不同:
静态变量可以通过类名调用,也可以通过对象调用
成员变量只能通过对象调用
main方法的格式:
public:公共的,访问权限是最大的,由于main方法是被jvm调用,所以权限要够大
static:静态的,不需要创建对象,通过类名就可以,方便jvm调用
void:方法的返回值是返回给调用者,而main方法是被jvm调用,返回内容给jvm没有意义
main:是一个常见的方法入口。几乎语言都是以main作为入口
String[] args:这是一个字符串数组
是早期为了接受键盘数据的
格式:java 类名 string... java
测试类的作用:创建其他类的对象,调用其它类的功能
在同一个文件夹下,类定义在两个文件中和调用在一个文件中其实一样的
方法改为静态后,就可以直接通过类名调用
如何制作说明书(帮助文档)
1:写一个工具类
2:对这个类加入文档注释
3:用工具解析文档注释
javadoc工具
4:格式
javadoc -d 目录 -author -version ArryTool.java
目录:写一个文件夹的路径
制作帮助文档出错:
找不到可以文档化的公共或受保护的类:告诉我们类的权限不够
java.lang包下的类不需要导入,其它的全部需要导入
看类的版本
类的结构:
成员变量 字段摘要
构造方法 构造方法摘要
成员方法 方法摘要
学习构造方法
有构造方法 就创建对象
没有构造方法 成员可能都是静态的
看方法
左边:
是否静态:如果静态,可以通过类名调用
返回值类型:人家 返回什么,就用什么接收
右边:
看方法名:方法名称不要写错
参数列表:人家要什么,就给什么;人家要几个,就给几个
java代码块:
java中,使用{}括起来的代码被称为代码块
根据其位置和声明不同,分为:
局部代码块:局部位置,用于限定变量的声生命周期。及早释放,提高内存利用率
构造代码块:在类中的成员位置,用{}括起来的代码,每次调用构造方法前,都会先执行构造代码块
作用:可以把多个构造方法中的共同代码放到一起,对对象进行初始化
静态代码块:在类中的成员位置,用{}括起来的代码,只不过它用static修饰
作用:一般是对类进行初始化
同步代码块:
执行顺序:
静态代码块 -- 构造代码块 -- 构造方法
静态代码块:执行一次
构造代码块:每次调用构造方法都执行
java继承:
多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那个类即可
格式:class 子类名 extends 父类名{}
单独这个类称为父类,基类,或者超类;这多个类称为子类或者派生类
在已经存在类的基础上,还可以定义自己的新成员
继承的好处:
提高了代码的复用性
多个类相同的成员可以放到一个类中
提高了代码的维护性
如果代码功能需要修改,修改一处即可
让类与类之间产生了关系,是多态的前提
其实这也是继承的一个弊端,类的耦合性很强
开发原则:低耦合,高内聚
耦合:类与类的关系
内聚:就是自己完成事情的能力
java继承特点:
java只支持单继承,不支持多继承
一个类只能有一个父类,不可以有多个父类
java支持多层继承(继承体系)
class A{}
class B extends A{}
class C extends C{}
java继承注意事项:
子类只能继承父类所有非私有的成员(成员变量,成员方法)
其实这也体现了继承的另一个弊端,打破了封装性
子类不能继承父类的构造方法,但是可以通过super关键字去访问父类构造方法
不要为了部分功能去继承
继承其实体现的是一种关系:"is a";采用假设法
继承中成员变量的关系:在子类中访问一个变量的查找顺序
名字一样
·1:在子类中的局部范围找,有就使用
2:在子类的成员范围找,有就使用
3:在父类的成员范围找,有就使用
4:如果还找不到,就报错
super的用法和this很像
this代表本类对应的引用
super代表父类存储空间的标识
用法:
访问成员变量:
this.成员变量 调用本类的成员变量
super.成员变量 调用父类的成员变量
访问构造方法
this(...) 调用本类的构造方法
super(...) 调用父类的构造方法
访问成员方法
this.成员方法 调用本类的成员方法
super.成员方法 调用父类的成员方法
继承中构造方法的关系:
子类中所有的构造方法默认都会访问父类中的空参数的构造方法
因为子类会继承父类中的数据,可能还会是用父类的数据,所以,子类初始化之前,一定要先完成父类数据的初始化
每一个构造方法的第一条语句默认都是:super();
this和super的区别:
继承中构造方法的注意事项:
如果父类没有无参构造方法,子类的构造方法会出现什么现象?子类报错
怎么解决
A:在父类中加一个无参构造方法
B:通过使用super关键字去显示的调用父类的带参构造方法
C:子类通过桃红色去调用本类的其他构造方法
子类中一定要有一个去访问了父类的构造方法,否则父类数据就没有初始化
注意事项:
this(...)和super(...)必须出现在第一条语句上
继承中成员方法关系:
子类中的方法和父类中的方法声明一样
通过子类调用方法:
1:先找子类中,看有没有这个方法,有就使用
2:再看父类中,有没有这个方法,有就使用
3:如果没有就报错
方法重载:本类中出现的方法名一样,参数列表不同的方法,与返回值无关
方法重写:子类中出现了和父类中方法声明一模一样的方法声明,也叫方法覆盖,方法复写
方法重写的应用:
当子类需要父类的功能,而功能主题子类有自己的特有的内容时,可以重写父类中的方法。这样,即沿袭了父类的功能,又定义了子类特有的内容。
方法重写的注意事项:
1:父类中的私有方法不能被重写:父类私有方法子类无法继承
2:子类重写父类方法时,访问权限不能更低:最好一致
3:父类静态方法。子类也必须通过静态方法进行重写(其实不算重写,多态讲)
子类重写方法的时候,最好声明一模一样
override:方法重写
overload:方法重载
API(Apilication Programming Interface)
应用程序编程接口(帮助文档)
由于继承中方法有一个现象:方法重写
所以父类的功能会被子类覆盖
java final关键字:最终的意思。常见的是它可以修饰类,方法,变量。
final的特点:
1:修饰类的特点:该类不能被继承。
2:修饰方法的特点:该方法不能被重写
3:修饰变量的特点:该变量不能被重新赋值。因为这个变量其实是常量
常量:
1:字面值常量:"hell0",10,true
2:自定义常量:final int x = 5;
final修饰局部变量的问题:
基本类型:基本类型的值不能发生改变
引用类型:引用类型的地址值不能发生改变,该对象的堆内存的值可以改变的
final修饰变量的初始化时机:
1:被final修饰的变量只能被赋值一次
2:在构造方法完毕前。(非静态的常量)
java多态
多态:某一个事物,在不同时刻表现出来的不同状态
多态前提和体现:
1:有继承关系或者实现关系
2:有方法重写
其实没有也是可以的,但是如果没有这个就没有意义
3:有父类或者父接口引用指向子类对象
Fu f = new Zi();
多态的分类:
1:具体类多态:
class Fu{}
class Zi extends Fu{}
Fu f = new Zi();
2:抽象类多态
abstract class Fu{}
class Zi extends Fu{}
Fu f =new Zi();
3:接口多态
interface Fu{}
class Zi implements Fu{}
Fu f = new Zi();
多态中成员的访问特点:
1:成员变量
编译看左边,即看Fu类中的成员变量
Fu f = new Zi();
运行看左边
2:构造方法
创建子类对象的时候,访问父类的构造方法,对父类的数据进行初始化
3:成员方法
编译看左边,运行看右边(方法存在覆盖)
4:静态方法
编译看左边,运行看右边(静态和类相关,算不上重写,所以访问还是左边的)
多态的好处:
1:提高了代码的维护性(继承保证)
2:提高了代码的拓展性(由多态保证)
多态的弊端:
不能使用子类的特有功能
怎么使用:
Fu f = new Zi();
方式1:创建子类对象调用方法即可(很多时候不合理,而且占内存)
方式2:Zi z = (Zi)f;
z.show();
z.method()
把父类的的引用强制转换为子类的引用。(向下转换)
多态对象间的转型问题:
向上转型:
Fu f = New Zi();
向下转型:
Zi z = (Zi)f; 要求改f必须是能够转换为Zi的
抽象类:在java中,一个没有方法体的方法应该定义为抽象类,如果类中有抽象方法,该类必须定义为抽象类
抽象类的特点:
1:抽象类和抽象方法必须用abstract关键字修饰
2:抽象类中不一定有抽象方法,但有抽象方法的类必须定义为抽象类
3:抽象类不能实例化
因为它不是具体的
抽象类有构造方法,但是不能实例化,用于子类访问父类数据的初始化
4:抽象类的子类
a:如果不想重写抽象方法,该子类是一个抽象类
b:重写所有的抽象方法,这个时候子类是一个具体的类
抽象类的实例化其实靠具体的子类实现的。是多态的方式
抽象类的成员特点:
成员变量:既可以是常量,也可以是变量
构造方法:有构造方法,不能实例化
作用:用于子类访问父类数据的初始化
成员方法:既可以是抽象的,也可以是非抽象的
抽象类的成员方法特性:
1:抽象方法,强制要求子类做的事情
2:非抽象方法,子类继承的事情,提高代码的复用性
abstract不能那些关键字共存:
private 冲突
final 冲突
static 无意义
接口:为了体现事物功能的拓展性,java中就提供了接口来定义这些额外功能,并不给出具体实现,将来那些类需要这些功能,只需这些类实现额外功能即可
接口特点:
1:接口用关键字interface表示
interface 接口名{}
2:类实现接口用implements表示
class 类名 implements 接口名{}
3:接口不能实例化
那么,接口如何实例化
按照多态的方式来实例化
由此可见:
1:具体类多态(几乎没有)
2:抽象类多态(常用)
3:接口多态(最常用)
4:接口的子类
1:可以是抽象类,但意义不大
2:可以是具体类。要重写接口中的所有抽象方法。(推荐方案)
接口成员特点:
成员变量:只能是常量,并且是静态的
默认修饰符:public static final(建议自己手动给出)
构造方法:接口没有构造方法
成员方法:只能是抽象方法
默认修饰符:public abstract
所有的类都默认继承自一个类:Object
类与类的关系:继承关系,只能单继承,可以多层继承
类与接口:
实现关系,可以单实现,也可以多实现
并且还可以在继承一个类的同时实现多个接口
接口与接口:
继承关系:可以单继承,也可以多继承。
抽象类和接口的区别:
1:成员区别
抽象类:
成员变量:可以变量,也可以常量
构造方法:有
成员方法:可以抽象,也可以不抽象
接口:
成员变量:只可以是常量
成员方法:只可以抽象
2:关系区别
类与类:
继承,单继承
类与接口:
实现,单实现,多实现
接口与接口:
继承,单继承,多继承
3:设计理念区别
抽象类 被继承体现的是:"is a"的关系。抽象类中定义的该继承体系的共性功能。
接口 被实现体现的是:"like a"的关系。接口中定义的是该继承体系的拓展功能。
形式参数:
基本类型:
引用类型:
类名:(匿名对象时讲过)需要的是该类的对象
抽象类名:需要的是该抽象类的子类对象
接口名:需要的是该接口的实现类对象
返回值类型
基本类型:
引用类型:
类:返回的是该类的对象
抽象类:返回的是该抽象类的子类对象
接口:返回的是该接口的实现类对象
链式编程:每次调用完毕方法后,返回的是一个对象
S1 s =new S1();
//S2 s2 = s.getXxx();
//s2.fun();
s.getXxx().fun();
包:其实就是文件夹
作用:
把相同的类名放到不同的包中
对类进行分类管理
按功能分:
按模块分:
包的定义:
packa 包名;多级包用.分开即可
注意事项:
1:package语句必须是程序的第一条可执行的代码
2:package语句在一个java文件中只能有一个
3:如果没有package,默认表示无包名
带包的编译和运行:
1:手动式:
a:编写一个带包的java文件
b:通过javac命令编译该java文件
c:手动创建包名
d:把b步骤的class文件放到c步骤的最底层包
e:回到和包根目录在同一目录的地方,然后运行
带包运行
java cn.itcat.HelloWorld
2:自动式:
a:编写一个带包的java文件
b:javac编译的时候带上-d即可
javac -d . HelloWorld.java
c:回到和包根目录在同一目录的地方,然后运行
带包运行
java cn.com.HelloWorld
不同包下类之间的访问:
导包概述:
不同包之下的类之间访问,我们发现,每次使用不同包下的类的时候,都需要加包的全路径,比较麻烦
这个时候。java就提供了导包的功能
导包格式
import 包名;
注意:
这种方式导入是到类的名字
虽然可以最后可以写*,但是不建议。
import com.fengzelang.Test;开发中用谁导谁
package>Import>class
package:只能有一个
import:可以有多个
class:可以有多个,以后建议是一个
权限修饰符:
修饰符 本类 同一个包下(子类和无关类) 不同包下(子类) 不同包下(无关类)
private Y
默认 Y Y
protected Y Y Y
public Y Y Y Y
类及其组成所使用的常见修饰符
权限修饰符:private,默认的,protected,public
状态修饰符:static,final
抽象修饰符:abstract
类:
权限修饰符:默认修饰符,public
状态修饰符:final
抽象修饰符:abstract
用的最多:public
成员变量:
权限修饰符:private,默认的,protected,public
状态修饰符:static,final
用的最多:private
构造方法:
权限修饰符:private,默认的,protected,public
用的最多:public
成员方法:
权限修饰符:private,默认的,protected,public
状态修饰符:static,final
抽象修饰符:abstract
用的最多:public
除此以外的组合规则:
成员变量:public static final
成员方法:public static
public abstract
public final
内部类概述:
把类定义在其他类的内部,这个类就被称为内部类
内部类的访问特点:
1:内部类可以访问外部类的成员,包括私有
2:外部类要访问内部类的成员,必须创建对象。
内部类的分类:
1:成员内部类
2:局部内部类
成员内部类
1:private为了数据的安全性
2:static为了访问 的方便性
成员内部类不是静态的:
外部类名.内部类名 对象名 = new 外部类名.new 内部类名();
成员内部类是静态的:
外部类名.内部类名 对象名 = new 外部类类名.内部类名();
静态内部类访问的外部类数据必须用静态修饰
成员内部类被静态修饰后的访问方式是:
格式:外部类名.内部类名 对象名 = new 外部类名.内部类名();
注意:
内部类和外部类没有继承关系
通过外部类名限定this对象
局部内部类:
1:可以直接访问外部类的成员
2:在局部位置,可以创建内部类的对象,通过对象调用内部类方法,来使用局部内部类功能
局部内部类访问局部变量的注意事项:
1:局部内部类访问局部变量必须用final修饰
因为局部变量会随着方法的调用完毕而消失,这个时候,局部对象并没有立马从堆内存中消失
还要继续使用哪个变量。为了让数据还能继续被使用,就用final。这样。在堆内存中存储的是常量
匿名内部类:
就是内部类的简化写法
前提:存在一个接口或者类
这里的类可以是具体类也可以是抽象类
格式:
new 类名或者接口(){
重写方法;
}
本质:
是一个继承了该类或者实现了该接口的子类匿名对象
interface Inter{
public abstract void show();
}
class Outer{
public void method(){
new Inter(){
public void show(){
System.out.println("show");
}
}.show();//对象调用方法
}
}
//多个方法很难调用
interface Inter{
public abstract void show();
public abstract void show2();
}
class Outer{
public void method(){
Inter i = new Inter(){//多态
public void show(){
System.out.println("show");
}
public void show2(){
System.out.println("show2");
}
};
i.show();
i.show2();
}
}
匿名内部类在开发中使用: