Java面向对象编程-类与对象
1.面向对象编程范式(C++、Java、Go)-能进行现实生活的抽象
狗吃屎
每个对象-类与对象
属性以及方法
OOA:面向对象分析
OOP:面向对象编程
OOD:面对对象设计
面向过程编程范式(c语言)
吃狗屎
面向切面编程(AOP)
面向接口编程-接口优先原则
函数式编程-Scala(JVM)
2.面对对象三大特征
封装性:将客观事物封装成为抽象的类,每个类都有自己的属性与方法,并且类可以让自己的数据
与方法只让可信的类或对象操作,对不可信的进行隐藏
内部操作对外部而言不可见(保护性)
继承性:可以使用现有类的所有功能,并且在无需重新编写原有类代码的情况下进行功能上的扩展
多态性:指一个类实例的相同方法在不同情形下有不同的表现形式
多态机制使得具有不同内部结构的对象可以共享相同的外部接口。(利用多态可以得到良好的设计)
3.Java中类与对象的定义与使用
类是共性的概念,而对象是一个具体的、可以使用的事物
类是生产对象的蓝图,先有类才可以产生对象。对象的所有属性与行为,一定在类中进行了完整的定义
class 类名称{
属性1;
属性2;
..
方法1(){}
方法2(){}
..
}
类中的属性与方法(不带static关键字的)只能通过对象调用
对象的产生语法
类名称 对象名称 = new 类名称();
4.对象内存分析
栈内存(虚拟机局部变量):存放的局部变量(各种基本数据类型、对象引用-对象名字)
堆内存:保存对象
new表示在堆上新分配空间
垃圾空间:没有任何栈内存指向的堆内存空间
5.private实现封装
将属性、方法用private封装后表示,被封装的属性和方法只能在本类中使用,类外部不可见
此时要想访问被封装的属性,必须提供getter和setterfangf
setter方法:主要进行属性内容的设置和修改
getter方法:主要获取属性的内容
类的设计原则:编写类的时候,没有额外说明,所有属性必须使用private封装(成员变量)
private可以使用在内部类前面,不能用于外部类前
6.构造方法
构造方法的三大特征:
构造方法的名称必须和类名称相同
构造方法没有返回值类型声明
每个类至少存在一个构造方法,如果没有明确定义,系统会自动生成无参构造
若在类中自定义了构造方法,则不会自动生成
构造方法重载
(参数个数不同)由于类属性已确定,所以不会有参数类型上的不同
7.类定义顺序
定义属性--定义构造方法--定义普通方法
8.this关键字
表示调用本类属性
只要在类中访问类的属性,一定要加this关键字
表示调用本类方法
调用普通方法 this.方法名(参数)
当有类的继承关系时,表示本类方法一定要加上this关键字
调用构造方法 this(参数) 不允许出现重复代码
this调用构造方法必须放在构造方法首行
this调用构造方法不允许成环
表示当前对象
9.static关键字
static变量-类属性(静态属性)
static属性为类属性,保存在全局数据区中(方法区-所有对象共享区域)
通过类名调用,与对象实例化无关
描述共享属性使用static属性(1%)
static方法-类方法(静态方法)
通过类名调用,与对象实例化无关,常用于工具方法
static可以使用在内部类前面,不能用于外部类前
10.代码块的定义与使用
根据代码块出现的位置及关键字,分以以下四种代码块
普通代码块
定义在方法中的代码块
构造块
定义在类中的代码块(不加任何修饰符)
在对象产生时优先于构造方法执行,有几个对象产生,就调用几个构造块
用于在构造方法执行前完成一些属性的初始化操作
静态代码块
非主类中的静态代码块
在类加载时执行(啥时候用到这个类),优先于构造块执行,无论产生多少对象,只会调用一次
主类中的静态代码块
主类中的静态块优先于主方法执行
同步代码块(多线程模块)
11.继承的定义与使用
在已有基础上进行功能上的扩充
判断俩个类之间能否使用继承:is a 公式
student is a person
Java中类的继承用extends关键字
子类(派生类)
父类(超类-基类)
继承的限制
子类对象实例化前首先调用父类构造方法产生父类对象后再调用子类构造方法实例化子类对象
3 6 7 2 1 5 4 2 1 5 4 8
Java中只允许单继承,不允许多继承(java单继承局限)
要想在Java中实现类似的"多继承",要么多层继承,要么使用内部类
在继承时,子类会继承父类所有结构(包含私有域与其他属性、方法)
显示继承:所有非私有操作属于显示继承(可以直接调用)
隐式继承:所有的私有操作属于隐式继承(不可以直接调用,只能通过其他方法调用)
12.覆写(重写)-override
定义:如果子类定义了与父类完全相同(不算权限)的方法或者属性的时候,这样的操作就成为覆写
方法的覆写
定义:子类定义了与父类方法名称、参数列表、返回值完全相同的方法。被覆写的方法不能拥有
比父类更为严格的访问控制权限
判断调用的到底是父类方法or子类方法
看new在哪(当前使用对象是通过哪个类new的)
调用的方法有没有被子类覆写,如果被覆写,调用的一定是被覆写后的方法
private< default-包访问权限 <public
方法覆写不能出现private关键字
请解释方法重载与方法重写区别
概念:
范围:
权限:
属性的覆写(了解)
13.super关键字
super用于方法
用于构造方法
当子类调用父类无参构造时,super()可写可不写,表示调用父类无参构造
当子类调用父类有参构造时,super(参数列表),必须要写,要告诉编译器当前调用的是哪个有参构造
子类构造方法中调用父类构造方法,必须是第一行语句
this()与super()不能同时调用,因为它俩都需要放在第一行
用于普通方法super.方法名(参数)
用于在子类中明确调用父类被覆写的方法
super用于属性(了解)
super.属性名 表示调用父类中被覆写的属性(权限不是private)
14.final关键字--终结器
final修饰类(String类以及8大基础数据结构类型的包装类,Integer)
当一个类被final修饰,表示该类不能拥有子类(该类不允许被继承)
一旦一个类被final修饰,该类所有方法都会默认加上final(成员变量不会加上final)
final修饰方法
当一个方法被final修饰,明确表示该方法不允许被覆写
当一个方法被private修饰后,相当于加了一个final
final修饰属性--常量
final修饰普通数据类型的成员变量(最主要的用途)
被final修饰的成员变量,必须在声明时初始化(构造块、构造方法),并且初始化后值无法被修改
final变量---常量
值不能改变,每个对象都有自己的final变量,在对象产生时初始化
static final - 全局常量
所有对象共享此变量,并且在类加载时初始化(静态代码块),效率较高,通过类名调用
全局常量命名规范:多个单词全大写,单词之间_隔开
final修饰引用数据类型的变量(值不能改变)
15.多态
向上转型(90%)
父类 父类引用 = new 子类();
向下转型(1%):当父类引用需要调用子类扩充方法时,才需要向下转型
子类 子类引用 = (子类)父类引用
要发生向下转型,必须先发生向上转型(认爹)
运行时异常:ClassCastException
引用名 instanceof 类:表示该引用是否能表示该类实例
16.内部类定义与使用
在类内部进行其他类结构嵌套操作
优点
内部类与外部类可以方便的访问彼此的私有域(私有方法、私有属性)
内部类是另外一种封装(保护性),对外部的其他类隐藏(心脏包在人体身体内部)
内部类可以实现Java单继承的局限
缺点
结构复杂
内部类与外部类的关系
对于非静态内部类,内部类的创建需要依赖外部类对象,在没有外部类实例之前无法创建非静态内部类
内部类是一个相对独立的个体,与外部类没有is-a关系
内部类可以直接访问外部类元素(包含私有域),但是外部类不可以直接访问内部类元素,需要通过内部
类引用间接访问
创建内部类语法(在外部类外部)
创建非静态内部类
外部类.内部类 内部类引用 = new 外部类().new 内部类();
Outter.Inner in = new Outter().new Inner();
创建静态内部类
外部类.内部类 内部类引用 = new 外部类().内部类()
Outter.Inner in = new Outter().Inner();
内部类的分类
存在私有内部类(静态、私有都可以)
ArrayList中的Node内部类 HashMap中Entry内部类
成员内部类(成员方法)
不能存在任何static变量或方法
成员内部类是依附于外部类的,所以只有先创建外部类才能创建内部类
静态内部类
静态内部类的创建不需要依赖外部类,可以直接创建
静态内部类不可以使用任何外部类的非static域(包含属性与方法的),但可以存在自己的成员变量
方法内部类
方法内部类不允许使用访问权限修饰符 public private protected均不允许
方法内部类对外部完全隐藏,除了创建这个类的方法可以访问以外,其他地方均不能访问
方法内部类如果要想使用方法形参,该形参必须使用final声明(JDK8将形参变为隐式final声明)
匿名内部类(lamdba表达式前身)
匿名内部类就是个没有名字的方法内部类,因此特点与方法内部类完全一样,除此之外
还有俩个自己的特点
匿名内部类必须继承一个抽象类或者实现一个接口
匿名内部类没有构造方法,因为它没有类名
17.抽象类与接口
抽象类的定义与使用
定义:抽象类只是在普通类的基础上扩充了一些抽象方法而已
抽象方法:指的是只声明而未实现的方法
所有抽象方法要求使用abstract来定义,并且抽象方法所在的类也一定要使用abstract来
定义,表示抽象类
抽象类的使用原则
抽象类必须有子类(abstract与final不能同时使用)
所有的抽象类子类必须覆写抽象类的所有抽象方法(abstract与private不能同时使用)
抽象类要想创建实例化对象,必须通过子类向上转型为其实例化(抽象类无法创建实例化对象)
抽象类的相关规定
抽象类也允许提供构造方法,并且子类也照样遵循对象实例化流程,先调用父类构造方法
后调用子类构造方法
抽象类允许不定义任何抽象方法,但是此时的抽象类依然无法直接创建实例化对象
abstrct与final不能同时使用
abstract与private不能同时使用
内部抽象类(了解)
模板设计模式-基于抽象类,核心是封装算法
开辟原则(OCP):一个软件实体如类、函数、模块应该对扩展开发、对修改关闭
模板方法定义了一个算法的步骤,并允许子类为一个或多个步骤提供具体实现
模板(模板方法)模式:Servlet AQS
在一个方法中定义一个算法的脊梁,并将一些具体步骤延迟到子类中实现
模板模式使得子类可以在不改变算法结构的基础上,重新具体定义算法的某些步骤
设计模式:第三方解耦
接口的定义与使用
接口优先原则:在一个操作既可以使用抽象类又可以使用接口的时候,优先考虑使用接口
接口定义:
接口就是一个抽象方法与全局常量的集合(JDK8之前)
接口使用interface定义
接口命名规范:接口定义前加I来区分接口与类
子类实现接口使用implements关键词,并且子类可以同时实现多个父接口(可以
使用接口来实现多继承)一般使用接口名+Impl来命名子类
接口使用限制
接口中只有public权限(不管属性还是方法,均为public)
接口中public static final abstract均可以省略
阿里编码规约:接口中方法加属性不加任何修饰符,public也不要加,保证代码简洁性
当一个子类既需要实现接口又需要继承抽象类时,请先使用extends继承一个抽象类,后
使用implements实现多个接口
抽象类可以使用implements实现接口,但是接口不能extends抽象类
接口可以使用extends继承多个父接口
接口应用
定义操作标准
表示一种能力,进行一项操作
在分布式开发中暴露远程服务方法
18.包的定义与使用(文件夹)
包的本质实际上就是文件夹
package
打包编译命令:javac -d . 类名.javac
-d:表示生成目录,根据package定义生成
.:表示在当前目录下生成子目录
包的导入
import
自动匹配编译顺序(在当前目录下按照主类的使用情况自动编译)
javac -d . ./*.java
系统常用包
java.lang 系统常用基础类(String、Object、包装类),JDK1.1之后自动导入
java.util java提供的工具程序包(集合类、ArrayList、HashMap),需要手工导入
juc java.util.concurrent 并发程序包
访问控制权限
private<default(包访问权限)<protected(继承访问权限)<public