目录结构
- 1.封装
- 2.面向对象之paivate关键字
- 3.面向对象之this关键字
- 4.面向对象之构造方法
- 5.创建对象的步骤
- 6.面向对象之static关键字的特点
- 7.静态变量和成员变量的区别
- 8.代码块
- 9.继承
- 10.this和super的区别
- 11.方法重写概述及其应用
- 12.final关键字概述
- 13.多态
- 14.多态的弊端和好处
- 15.抽象类特点
- 16.接口特点
- 17.类与类,类与接口,接口与接口的关系
- 18.抽象类与接口的区别
- 19.面向对象之类名作为形式参数
- 20.面向对象之抽象类名作为形式参数
- 21.面向对象之接口名作为形式参数
- 22.面向对象之类名作为返回值类型
- 23.面向对象之抽象类名作为返回值类型
- 24.面向对象之接口名作为返回值类型
- 25.包的定义及package
- 26.import关键字的概述和使用
- 27.四种权限修饰符的测试
- 28.类及其组成所使用的常见修饰符
- 29.内部类概述和访问特点
- 30.匿名内部类
1.封装
- 1.1 封装的概述
- 封装概述
- 是指隐藏对象的属性和实现细节,仅对外提供公共访问方式。
- 封装好处
- 隐藏实现细节,提供公共的访问方式
- 提高代码复用性
- 提高安全性
- 封装原则
- 将不需要对外提供的内容都隐藏起来。
- 把属性隐藏,提供公共方法对其访问。
2.面向对象之paivate关键字
- private关键字特点
- 是一个权限修饰符
- 可以修饰成员变量和成员方法
- 被其修饰的成员只能在本类中被访问
- private最常见的应用
- 把成员变量用private修饰,提供对应的getXxx()和setXxx()方法
3.面向对象之this关键字
- 为什么要有this
- 当我们的局部变量和成员变量相同的时候,如果我们不使用this关键字,那么会导致一个问题:就是局部变量隐藏了成员变量的问题
- this关键字特点
- 是当前类的对象引用
- 简单的记,它就代表当前类的一个对象。谁调用这个方法,那么该方法的内部的this就代表谁
- this的应用场景
4.面向对象之构造方法
- 构造方法概述和作用
- 构造方法格式特点
- 方法名与类名相同;没有返回值类型,连void都没有
- 构造方法注意事项
- 如果我们没有给出构造方法,系统将自动提供一个无参构造方法。
- 如果我们给出了构造方法,系统将不再提供默认的无参构造方法。
- 注意:这个时候,如果我们还想使用无参构造方法,就必须自己给出。建议永远自己给出无参构造方法
5.创建对象的步骤
- 对象的创建步骤
- (1):加载A.class文件进内存
- (2):在栈内存为s开辟空间
- (3):在堆内存为学生对象开辟空间
- (4):对学生对象的成员变量进行默认初始化
- (5):对学生对象的成员变量进行显示初始化
- (6):通过构造方法对学生对象的成员变量赋值
- (7):学生对象初始化完毕,把对象地址赋值给s变量
6.面向对象之static关键字的特点
- 6.1 static关键字的特点
- 随着类的加载而加载
- 优先于对象存在
- 被类的所有对象共享
- 可以通过类名调用【静态修饰的内容一般我们称其为:与类相关的,类成员】
- 6.2 static的注意事项
- 在静态方法中是没有this关键字的
- 静态是随着类的加载而加载,this是随着对象的创建而存在。
- 静态比对象先存在。
- 静态方法只能访问静态的成员变量和静态的成员方法【静态只能访问静态,非静态可以访问静态的也可以访问非静态的】
7.静态变量和成员变量的区别
- A:所属不同
- 静态变量属于类,所以也称为类变量
- 成员变量属于对象,所以也称为实例变量(对象变量)
- B:内存中位置不同
- 静态变量存储于方法区的静态区
- 成员变量存储于堆内存
- C:内存出现时间不同
- 静态变量随着类的加载而加载,随着类的消失而消失
- 成员变量随着对象的创建而存在,随着对象的消失而消失
- D:调用不同
- 静态变量可以通过类名调用,也可以通过对象调用
- 成员变量只能通过对象名调用
8.代码块
- A:代码块概述
- B:代码块分类
- 根据其位置和声明的不同,可以分为局部代码块,构造代码块,静态代码块,同步代码块。
- C:常见代码块的应用
- a:局部代码块
- 在方法中出现;限定变量生命周期,及早释放,提高内存利用率
- b:构造代码块
- 在类中方法外出现;多个构造方法方法中相同的代码存放到一起,每次调用构造都执行,并且在构造方法前执行
- c:静态代码块
- 在类中方法外出现,加了static修饰
- 在类中方法外出现,并加上static修饰;用于给类进行初始化,在加载的时候就执行,并且只执行一次。
9.继承
- 9.1 继承概述
- 多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那个类即可。
- 9.2 继承格式
- 通过extends关键字可以实现类与类的继承
- class 子类名 extends 父类名 {}
- 单独的这个类称为父类,基类或者超类;这多个类可以称为子类或者派生类
- 9.3 继承的好处
- a:提高了代码的复用性
- b:提高了代码的维护性
- c:让类与类之间产生了关系,是多态的前提
- 9.4 继承的弊端
- 类的耦合性增强了。
- 开发的原则:高内聚,低耦合。
- 耦合:类与类的关系
- 内聚:就是自己完成某件事情的能力
- 9.5 继承的注意事项
- a:子类只能继承父类所有非私有的成员(成员方法和成员变量)
- b:子类不能继承父类的构造方法,但是可以通过super(待会儿讲)关键字去访问父类构造方法。
- c:不要为了部分功能而去继承
- 9.6 继承中成员变量的关系
- A:子类中的成员变量和父类中的成员变量名称不一样
- B:子类中的成员变量和父类中的成员变量名称一样
- 在子类中访问一个变量的查找顺序("就近原则")
- a: 在子类的方法的局部范围找,有就使用
- b: 在子类的成员范围找,有就使用
- c: 在父类的成员范围找,有就使用
- 9.7 继承中构造方法的注意事项
- 父类没有无参构造方法,子类怎么办?
- a: 在父类中添加一个无参的构造方法
- b:子类通过super去显示调用父类其他的带参的构造方法
- c:子类通过this去调用本类的其他构造方法
- 本类其他构造也必须首先访问了父类构造
- B:注意事项
- super(…)或者this(….)必须出现在第一条语句上
10.this和super的区别
- A:通过问题引出super
- B:说说this和super的区别
- this 代表的是本类对象的引用
- super 代表的是父类存储空间的标识(可以理解成父类的引用,可以操作父类的成员)
- C:this和super的使用
- a:调用成员变量
- this.成员变量 调用本类的成员变量
- super.成员变量 调用父类的成员变量
- b:调用构造方法
- this(...) 调用本类的构造方法
- super(...) 调用父类的构造方法
- c:调用成员方法
- this.成员方法 调用本类的成员方法
- super.成员方法 调用父类的成员方法
11.方法重写概述及其应用
- A:什么是方法重写
- 子类中出现了和父类中一模一样的方法声明(方法名,参数列表,返回值类型),也被称为方法覆盖,方法复写。
- B: Override和Overload的区别?Overload能改变返回值类型吗?
- C:方法重写的应用
- 当子类需要父类的功能,而功能主体子类有自己特有内容时,可以重写父类中的方法。
- 这样,即沿袭了父类的功能,又定义了子类特有的内容。
- 方法重写注意事项
- a:父类中私有方法不能被重写 ,因为父类私有方法子类根本就无法继承
- b:子类重写父类方法时,访问权限不能更低 ,最好就一致
- c:父类静态方法,子类也必须通过静态方法进行重写 ,其实这个算不上方法重写,但是现象确实如此,至于为什么算不上方法重写,多态中我会讲解
12.final关键字概述
- A:为什么会有final
- 由于继承中有一个方法重写的现象,而有时候我们不想让子类去重写父类的方法.这对这种情况java就给我们提供了一个关键字: final
- B:final概述
- final关键字是最终的意思,可以修饰类,变量,成员方法。
- C:final修饰特点
- 修饰类: 被修饰类不能被继承
- 修饰方法: 被修饰的方法不能被重写
- 修饰变量: 被修饰的变量不能被重新赋值,因为这个量其实是一个常量
- **D:final关键字修饰局部变量 **
- 基本类型,是值不能被改变
- 引用类型,是地址值不能被改变
19.面向对象之类名作为形式参数
/*要的都是对象具体类的作为参数传递的问题*/
class Student {
public void show() {
System.out.println("student.....show.............") ;
}
}
class StudentDemo {
public void method(Student s) {
s.show() ;
}
}
// 测试类
class ArgsDemo {
public static void main(String[] args) {
// 创建StudentDemo的对象
StudentDemo sd = new StudentDemo() ;
// 创建Student的对象
Student s = new Student() ;
// 调用方法
// sd.method(s) ;
sd.method(new Student()) ;
}
}
20.面向对象之抽象类名作为形式参数
/*抽象类作为参数的时候如何进行调用*/
abstract class Animal {
// 定义一个抽象方法
public abstract void eat() ;
}
// 定义一个类
class Cat extends Animal {
public void eat(){
System.out.println("吃.................") ;
}
}
// 定义一个类
class AnimalDemo {
public void method(Animal a) {
a.eat() ;
}
}
// 测试类
class ArgsDemo2 {
public static void main(String[] args) {
// 创建AnimalDemo的对象
AnimalDemo ad = new AnimalDemo() ;
// 对Animal进行间接实例化
// Animal a = new Cat() ;
Cat a = new Cat() ;
// 调用method方法
ad.method(a) ;
}
}
21.面向对象之接口名作为形式参数
/*接口作为参数的时候我们如何进行调用*/
interface Jump {
// 跳高接口
public abstract void jump() ;
}
// 定义一个子类
class JumpImpl implements Jump {
public void jump(){
System.out.println("jump.............................") ;
}
}
// 定义一个类
class JumpDemo {
public void method(Jump jump) {
jump.jump();
}
}
// 测试类
class ArgsDemo3 {
public static void main(String[] args) {
// 1. 创建JumpDemo对象
JumpDemo jd = new JumpDemo() ;
// 2. 调用method方法
// 对Jump进行间接实例化
Jump jump = new JumpImpl() ;
jd.method(jump) ;
}
}
22.面向对象之类名作为返回值类型
/*具体类作为返回值类型*/
class Student {
public void show() {
System.out.println("student....show.....................") ;
}
}
// 定义一个类
class StudentDemo {
public Student getStudent() {
return new Student() ;
}
}
// 测试类
class ReturnDemo {
public static void main(String[] args) {
// 创建StudentDemo的对象
StudentDemo sd = new StudentDemo() ;
// 调用 public Student getStudent()
Student s = sd.getStudent() ;
// 调用方法
s.show() ;
}
}
23.面向对象之抽象类名作为返回值类型
/*抽象类作为返回值类型*/
abstract class Animal {
public abstract void eat() ;
}
// 定义一个子类
class Cat extends Animal {
public void eat(){
System.out.println("吃..........................") ;
}
}
// 定义一个类
class AnimalDemo {
public static Animal getAnimal() {
// Animal a = new Cat() ;
// return a;
return new Cat() ;
}
}
// 测试类
class ReturnDemo2 {
public static void main(String[] args) {
// 调用AnimalDemo的getAnimal这个方法
Animal a = AnimalDemo.getAnimal() ;
// 调用方法
a.eat() ;
}
}
24.面向对象之接口名作为返回值类型
/*接口作为返回值类型*/
interface Jump {
public abstract void jump() ;
}
// 定义一个子类
class JumpImpl implements Jump {
public void jump(){
System.out.println("jum....................") ;
}
}
// 定义一个类
class JumpDemo {
public static Jump getJump() {
return new JumpImpl() ;
}
}
// 测试类
class ReturnDemo3 {
public static void main(String[] args) {
// 调用getJump方法
Jump jump = JumpDemo.getJump() ;
// 调用
jump.jump() ;
}
}
25.包的定义及package
- 25.1 package关键字的概述及作用
- A:包的概述: 就是文件夹
- B:包的作用: 用来解决同一个路径下不能存在同名文件的问题(分类管理)
- C:包的划分: 按照功能,按照模块
- 25.2 包的定义及注意事项
- A:定义包的格式
- B:定义包的注意事项
- A:package语句必须是程序的第一条可执行的代码
- B:package语句在一个java文件中只能有一个
- C:如果没有package,默认表示无包名
26.import关键字的概述和使用
- A:导包的概述
- 不同包下的类之间的访问,我们发现,每次使用不同包下的类的时候,都需要加包的全路径。比较麻烦。这个时候,java就提供了导包的功能
- B:导包格式
- import 包名;
- 注意:
- 这种方式导入是到类的名称。
- 虽然可以最后写*,但是不建议。
27.四种权限修饰符的测试
- 修饰符
- 四种权限修饰符: private(私有的) , 默认 , protected(受保护的) , public(公共的)
- 结论
* 本类 同一个包下 不同包下(子类) 不同包下(无关类)
* private Y
* 默认 Y Y
* protected Y Y Y
* public Y Y Y Y
28.类及其组成所使用的常见修饰符
- A:修饰符:
- 权限修饰符:private,默认的,protected,public
- 状态修饰符:static,final
- 抽象修饰符:abstract
- B:类:
- 权限修饰符:默认修饰符,public
- 状态修饰符:final
- 抽象修饰符:abstract
- 用的最多的就是:public
- C:成员变量:
- 权限修饰符:private,默认的,protected,public
- 状态修饰符:static,final
- 用的最多的就是:private
- D:构造方法:
- 权限修饰符:private,默认的,protected,public
- 用的最多的就是:public
- E:成员方法:
- 权限修饰符:private,默认的,protected,public
- 状态修饰符:static,final
- 抽象修饰符:abstract
- 用的最多的就是:public
- F:除此以外的组合规则:
- 成员变量: public static final
- 成员方法: public static / public abstract / public final
29.内部类概述和访问特点
- A:内部类概述:
- 把类定义在其他类的内部,这个类就被称为内部类。
- 举例:在类A中定义了一个类B,类B就是内部类。
- B:内部类访问特点
- a:内部类可以直接访问外部类的成员,包括私有。
- b:外部类要访问内部类的成员,必须创建对象。
- 29.1 内部类分类及成员内部类的直接使用
- A:按照内部类位置分类
- 成员位置:在成员位置定义的类,被称为成员内部类。
- 局部位置:在局部位置定义的类,被称为局部内部类。
- B:成员内部类
- 如何在测试类中直接访问内部类的成员。
- 格式: 外部类名.内部类名 对象名 = 外部类对象.内部类对象;
- 29.2 成员内部类的常见修饰符及应用
- A:成员内部类的修饰符:
- private 为了保证数据的安全性
- static 为了方便访问数据
- 注意事项:
- a:静态内部类访问的外部类数据必须用静态修饰。
- b: 成员方法可以是静态的也可以是非静态的
- B:成员内部类被静态修饰后的访问方式是: * 格式: 外部类名.内部类名 对象名 = new 外部类名.内部类名();
- 29.3 局部内部类访问局部变量的问题
- A: 可以直接访问外部类的成员
- B: 可以创建内部类对象,通过对象调用内部类方法,来使用局部内部类功能
- C:局部内部类访问局部变量必须用final修饰
- 为什么呢?
- 因为局部变量会随着方法的调用完毕而消失,这个时候,局部对象并没有立马从堆内存中消失,还要使用那个变量。 为了让数据还能继续被使用,就用fianl修饰,这样,在堆内存里面存储的其实是一个常量值。
- 当我们添加了final其实就是延长了生命周期 , 其实就是一个常量 , 常量在常量池中 , 在方法区中
30.匿名内部类
- 30.1 匿名内部类的格式和理解
- A:匿名内部类: 就是局部内部类的简化写法。
- B:前提: 存在一个类或者接口;这里的类可以是具体类也可以是抽象类。
- C:格式:
new 类名或者接口名(){
重写方法;
} ;
- 30.2 本质是什么呢?
- 是一个继承了该类或者实现了该接口的子类匿名对象。
- 匿名内部类的面试题
按照要求,补齐代码
interface Inter { void show(); }
class Outer { //补齐代码 }
class OuterDemo {
public static void main(String[] args) {
Outer.method().show();
}
}
要求在控制台输出”HelloWorld”
- 答案
//补齐代码
public static Inter method() {
//匿名内部类
return new Inter() {
public void show(){
System.out.println("HelloWorld") ;
} ;
}
}