面向对象
面向对象
Object
对象是现实世界的独立个体
属性:个体的状态信息(数据)(可以改变)
行为:个体可以做什么(操作)
对象具有类变之分
对象与类
创建对象 类名 对象名=new 类名();
对象名.访问
类:创造对象的模板 类抽取了同类别的所有对象属性和行为上的共性,一个类可以描述千千万万个对象
不同类创建的对象:属性和行为往往具有差异
同类型创建的对象:取值往往也具有差异
不同对象调用同一个成员方法 结果也不同
方法不能嵌套定义,但是类可以嵌套定义 在里面的类是内部类
在类中,用成员变量描述全体对象的共性(有默认值)
在类中,用成员方法描述全体对象的行为
package com.sckaoyan.javase;
public class Introduction {
//成员位置
public static void main(String[] args) {
//局部位置
Student s = new Student();
s.study();
s.sleep();
System.out.println(s.age);
Student s_2 = new Student();
s_2.name="张三";
System.out.println(s_2.name);
System.out.println(s.name);
s_2.sleep();
System.out.println(s);
System.out.println(s_2==s);
}
}
//学生类
class Student{
//属性
String name;
int age;
int id;
double score;
//抽取全体对象行为的共性,得到成员方法
public void study(){
System.out.println("好好学习,天天向上");
}
public void sleep(){
System.out.println(name+"你这个年龄段睡得着觉?");
}
}
成员变量与局部变量
5.作用范围:
成员变量:在整个类中的成员方法中,都是可以被访问的,作用范围在
局部变量:
引用数据类型
分为两部分: 字体改成红色了
①栈上创建引用,它是一个局部变量
②在堆上开辟空间,创建对象
栈上的引用通过存储堆上对象的地址和对象产生联系
基本数据类型的和类的引用有什么不同:
①基本数据类型在Jvm之前已经定义好了:
②类的引用数据类型:Jvm需要先类加载(认识),类加载通过I/O流(效率低)的形式将某个类的字节码文件读取进方法区,经过一系列过程,从而认识该数据类型。
类加载时机: ①new对象②启动某个类静态成员变量或方法③启动某个类的main方法
触发一次加载,后续不许再加载了
构造方法
访问权限修饰符 类名 (形参列表){
//构造方法体
}
构造器的作用:
默认无参构造器:public 类名(){} 不能给成员变量赋值
有参构造器:public 类名(变量名1,变量名2...){
this.成员变量=局部变量;
}
类中的构造器之间是方法的重载关系
构造器的赋值永远在最后一步
注意:类中如果存在一个显示写出的构造器,那么默认无参就不会提供了
①在java当中,只要使用new关键字创建对象,那么必然调用构造器,构造器是jvm创建对象的过程中,jvm去调用,用于给对象的成员变量赋值:
②构造器不是由程序员调用,但是程序员可以指定JVM调用哪个构造器 语法:new 类名(实参列表)
this关键字指向当前对象
this关键字的作用:在成员方法中,用来区分同名的成员变量和方法形参的局部变量
static方法不是成员方法
package com.sckaoyan.javase;
public class This {
public static void main(String[] args) {
A a = new A();
a.setNum(10);
}
}
class A{
int num;
public void setNum(int num){
System.out.println(this.num=num);
}
}
★访问权限修饰符
pulblic:(公共) 不同包中的其它类可以
protected:不同包的子类可以访问
default(不写出来):同一包中的子类或其它类能够访问,同包下可以访问
private:仅在类中可以使用
1.修饰类 只有2种访问权限 1.public 2.缺省
2.修饰成员或构造器或内部类 4种访问权限都可用
工厂设计模式:指的是不通过自身构造器创建对象,而是通过工厂去创建对象。
单例模式:在整个JVM全局保持这个类的对象唯一
懒汉模式:用到对象时才创建
饿汉模式:类加载时就创建对象
工具类应该私有化构造器
没有class的访问权限,不能访问class中成员
约定:在正常的开发中我们一般只会定义一个public class,很少定义非public类
类名:大驼峰
static关键字
Static关键字修饰的成员变量,是静态成员变量,不属于对象,而属于类
Static关键字修饰的成员方法,是静态成员方法,不属于对象,而属于类
[访问修饰符] static 数据类型 变量名;
静态成员和类加载一起进行
访问用 类名.静态成员变量
匿名对象
Student s=new Student(); //正常创建对象
new Student(); //匿名对象 (一次性)
调用方法:new Student().方法名
★代码块
定义:由若干条Java语句组成,并且用一对大括号括起来的结构,叫做代码块。
局部代码块:局部位置 局部代码不能用static修饰
静态代码块:和static有关 声明在类的成员位置
//成员位置
static{
//代码静态块
}
//成员位置
不能访问非静态成员
可以把静态代码块看成是一个在类加载过程中,自动被调用的静态成员方法
显示赋值和静态代码块按先后顺序执行
构造代码块:和构造器有关 声明在类的成员位置
//成员位置
{
//构造代码块
}
//成员位置
构造代码块需要new对象后才执行
编译器编译后,不存在代码块这种结构
编译器会智能将显式赋值和构造代码块赋值按先后顺序,将最后执行的代码放在构造器中!
随构造器执行而执行,用于创建对象赋值
同步代码块
类加载
1.加载:主要将class字节码文件读取进JVM
连接(2,3,4)
2.验证:class字节码文件是否合法
3.准备: 进行静态成员变量的默认初始化
4.解析:符号引用转换成直接引用(地址)
5.初始化:执行和static相关的内容
创建对象在初始化之前,初始化仅有一次
静态成员变量的显式赋值,在初始化时执行
6.使用:
7.卸载:
包名
package:声明关键字,它后面跟上包名用.隔开,用来声明Java文件下,所有的class文件
import:导入包名(全限定类名)
import 包名.* (根据需要导入该类的全部包)
(了解)静态导入: import static 某个类的包名+类名+静态成员名字
封装,继承,多态 (面向对象三答特征)
封装
数据的隐藏,通常要禁止直接访问一个数据的实际表示,而应通过接口来访问
遵循:“高内聚,低耦合”原则,不允许外部干涉
属性私有,get/set
public String getName(){
return name;
}
public String setName(){
this.变量名=变量名;
}
继承
继承关系的两个类,一个为子类(派生类),一个为父类(基类)。子类继承父类,使用关键字extends表示
子类通过继承父类,会得到父类中的所有成员
Java中类只有单继承没有多继承
继承不考虑静态成员,继续考虑对象。
何时用继承???
子类“is-a”父类
1.触发类加载 “先父后子”
2.类加载结束后,开始创建对象,仅会创建一个子类对象,不会创建父类对象
3.创建子类对象后,会在堆中开辟一片空间,用于独属于父类成员(近似看成父类对象super),子类对象成员和父类成员存放的区域不同。
子类对象的初始化过程:①类加载先父后子②开始创建子类对象(不创建父类对象)③开辟一片空间,用于存储父类成员,super近似指向父类成员④父类的构造器在子类的构造器前执行
引用数据类型
引用数据类型有几种类型转换:
①自动类型转换 (编译器自动完成类型转换)
②强制类型转换
super关键字
super调用父类的构造方法必须放在第一个
super只能出现在子类的方法或构造方法中
super和this不能同时调用构造方法
super与this的区别:
代表的对象不同:
this:本身调用者的对象 super:父类(近似对象)的引用
前提
this:没有继承也可以用
super:只能在有继承之后才能使用构造方法
构造方法:
this:本类的构造
super:父类的构造
★方法重写
在子类中,能够改写父类成员方法的内容。从形式上表现出来,就是父子类中能够拥有同名的成员方法。
重写须加注解 @Override 不然报错
//父类方法
public void fly(){
System.out.println("飞飞");
}
//子类方法 @Override
public void fly(){
System.out.println("我不会飞了");
}
static、final、private,构造器修饰的方法不能重写
多态
一个方法可以根据发送对象的不同而采取不同的行为方式
一个对象的实际类型是确定的,但可以指向对象的引用的类型有很多
在Java的多态当中,多态指的是:
- 同一种事物:同一个引用(即父类的引用)
- 不同的情况:指向不同的对象(不同的子类对象)
- 不同的状态:调用同名方法会体现出不同的行为
Java中的多态指的是,同一个父类引用指向不同子类对象时,调用同名成员方法,根据指向实际对象的不同,得到的行为也会随之不不同。
多态存在的条件:
有继承关系
子类重写父类方法
父类引用指向子类对象
不能发生多态的场景:
不能继承的类,即final修饰的类。一个final修饰的类都没有子类
不能重写的方法,不能重写也没有多态。不能重写的方法有:
- private方法,没有权限重写。
- 构造方法,不能继承。
对象名.成员变量 访问范围和结果都只看引用
对象名.成员方法
编译时(访问范围)看左边,运行时(访问结果)还看左边。
instanceof
条件:必须父子关系
//(引用 instanceof 类/接口 ) X是Y的子类 返回true
System.out.println(p instanceof Student);
方法的覆盖
final关键字
可以修饰 类,方法,变量
[访问权限修饰符] static final 数据类型 变量名;
final修饰类时,表示最终的类,就说这个类不能被继承
final修饰方法,表示最终的方法,该方法不能被重写(可以继承)
final修饰变量,表示最终的变量(常量),
final修饰引用数据类型,表示引用成为了一个常量,引用不能再指向一个新的对象了。但是对象的状态可以改变。
抽象类和接口
抽象方法(Abstract)
abstract可以修饰
抽象方法
public abstract void fun();
抽象类:可以定义抽象方法的普通类
[访问修饰符]
abstract class 类名{
}
抽象类可以没抽象方法,但是抽象方法的类一定要申明抽象类。
抽象类成员特点:可以有普通成员,静态成员,构造方法,代码块,抽象方法。
抽象类继承抽象类,无需强制实现父类的抽象方法!
抽象类,不能使用new关键字来创建对象,
抽象方法,只有方法的声明,没有方法的实现,必须子类来实现。
不能修饰以下方法:private 私有方法 static方法 构造方法
子类继承抽象类,必须重写抽象类中没有实现的抽象方法,否则该子类也要声明为抽象类!
接口
定义:只有规范!自己不能写方法~专业的约束!约束和实现分离:面向接口编程!
[访问权限修饰符(public或默认)] interface 接口名{}
接口中允许定义抽象方法
可以继承某个类时,再继承接口
可以同时实现多个接口
接口中没有变量,接口中的变量默认都是“public static final ”修饰的常量
不允许定义静态代码块
接口中能够定义的内容都是public修饰的
接口无构造器 不能创建对象
接口无代码块
JDK8及之后版本允许在接口自定义实现方法,
声明接口的关键字是interface
继承接口的关键字是implements
内部类
成员内部类:
在外围类中再声明一个普通类
内部类和外围类是“好兄弟”,它们之间的访问不受访问权限限制。
访问权限:四种访问权限均可用
成员特点:①成员内部类可以看成该类的一个成员。所以,想要得到成员内部类对象,必须先
创建外围类对象。
②创建对象会触发类加载,即便是内部类也不例外。
继承和实现:①内部类可以继承和实现外部的类和接口。
②也可以在类中定义多个普通类、抽象内部 类和接口用来自己继承和实现。
访问特点:
成员内部类内部访问外围类:就近原则,自身对象用this,外围类对象 用 外围类名.this
不受访问权限
外围类访问成员内部类成员:
①外围类访问成员内部类成员:创建对象后,直接用对象名点访问即可 不受访问权限
②成员内部类对象依赖外围类对象而存在, 所以得先存在外围类对象才行。但静态方法中什么对象都没有,就需要先创建外围类对象,再创建成员内部类对象。 不受访问权限
InnerClazz mic = new EnclosedClazz().new InnerClazz();
外部类访问成员内部类成员: 受访问权限限制
EnclosedClazz.InnerClazz ic = new EnclosedClazz().new InnerClazz();
成员内部类访问外部类成员:
1.静态成员直接类名点访问。2.普通成员需创建外部类对象去访问。3.受访问权限控制
静态内部类:
在外围类中再声明一个静态类
访问权限:四种访问权限均可用
成员特点:静态内部类和外围类本质上是两个独立的类
静态内部类和外围类的类加载不会相互触发
继承和实现:只能继承静态内部类
访问特点:静态内部类和外围类互相访问不受权限限制
1.静态内部类访问外围类 创建对象 不受访问权限
2.外围类访问静态内部类成员 创建对象 不受访问权限
3.外部类访问静态内部类成员 创建静态内部类对象 受访问权限
4.静态内部类访问外部类成员 创建对象 受访问权限
局部内部类:
局部内部类中的局部变量是常量!
定义局部位置的类
访问修饰符:没有访问修饰符
成员特点:没有static声明,但是可以定义不触发类加载的全局常量
继承与实现:可以继承和实现外部的类或接口
访问特点:
局部内部类访问外围类: 直接访问 不受权限限制
外围类访问局部内部类成员: 必须在作用域内创建对象,不受权限限制
外部类访问局部内部类成员: 不能访问
局部内部类访问外部类成员: 创建对象访问,受权限限制
优点:绝对对外界隐藏,封装!
缺点:类是一次性的
匿名内部类(对象)
定义在方法等局部位置
语法:
/*IA ia= */ new IA(//调用父类的构造器传参){
//匿名子类无构造器
//定义成员或重写方法
@Override
public void test() {
}
}/*.test() 可以调用局部方法;*/ ;
Outer outer=new Outer();
Outer.Inner inner=Outer.new Inner();
优点:
直接使用:简单,不需要接收直接使用
可以访问匿名子类的独有成员
间接使用:引用可以多次使用匿名内部类
缺点:
- 一次性
2.使用的是引用父类
无法访问子类独有成员
Lambda
Lambda表达式仍然数局部内部类
语法:
() -> {}
()是功能接口中,哪个必须要子类重写的抽象方法的形参列表
-> 读作"go to",运算符
{}是功能接口中,哪个必须要子类重写的抽象方法的重写方法体
简化:
()
无参 小括号不能省略
单参 可以省略小括号
双参 可以省略形参的数据类型
{}
重写方法体的只有一条语句 省略{}
方法体只有一条语句且是返回值语句 {} return都可省略
1.不省略”->“的写法
(形参列表) ->已实现的方法(形参列表)
①.静态方法 类名.调用
②.成员方法 对象名.调用
2.省略”->“的写法(推荐)
方法的归属者(类,对象)::方法名
1.Lambda表达式时特殊的局部内部类,访问方法的局部变量,该变量是final修饰的常量
2.{}和装有Lamba表达式的作用域共用一个作用域
3.Lambda可以引用已存在写好的方法(包括源码)
回调方法:可以传入另外一个方法的方法(Lambda表达式本质是传入一个方法的实现)
对象内存图
成员变量的赋值(顺序与结果)
代码知识点
包名+类名=全限定类名
new关键字 表示在堆上开辟空间创建对象
new 类名().var 快捷new对象
Car car = new Car();
快捷构造器:Alt+Insert
1.默认赋值
2.显式赋值
3.构造器赋值
4.构造代码块赋值
顺序:默认赋值最先,构造器赋值最后 显示赋值和构造代码块按先后顺序
知识点简答题
-
二维数组的本质是什么?内存中存在二维数组的特殊内存结构吗?
答:是一维数组成为了另一个一维数组的元素,一维数组装一维数组。 没有的
-
什么是类?什么是对象?(根据自己理解写一下即可)
答:对象:对应现实中存在的个体,Ta们具有特定的属性和特定的行为 类:类就是创建对象的模板,并抽取了同类别的所有对象属性和行为上的共性
-
创建对象和类加载谁先谁后?某个类的类加载在程序某一次运行过程中,有几次?
答:先类加载再创建对象,只有一次
-
包装类有哪些?简要描述一下。
答:1、Byte 2、Integer 3、Short 4、Long 5、Float 6、Double 7、Boolean 8、Character。
-
对于下述代码:
public class Demo{ public static void main(String[] args){ Demo d = new Demo(); } }main方法中创建Demo对象,会触发Demo类的类加载吗?
我们把一定会触发类加载的场景,称之为类加载的时机。总结目前为止,类加载的时机。
答:会,先Demo类加载,再创建Demo对象
-
创建对象过程中,成员变量的赋值有很多手段,总结到目前为止成员变量的赋值方式。并谈一谈它们执行的先后顺序。
答:构造方法,默认赋值,在类里手动赋值。 先默认赋值,再手动赋值,最后是构造方法!
-
访问父类中受保护(prootected)的成员,有几种方式?
1.创建自身类对象访问
快捷键
AIT+ENTER 导包
AIT+INSERT 生成set,get方法

浙公网安备 33010602011771号