JavaSE05-面向对象编程
前言
-
掌握面向对象和面向过程的概念
-
掌握面向对象的三大特征
-
掌握抽象类和接口的区别
-
掌握初始化对象时的执行顺序
一、面向对象&面向过程
1.面向过程思想
-
按步骤执行,第一步做什么,第二步做什么。。。(处理较简单的问题)
2.面向对象思想
-
分类的思维模式(物以类聚)。
-
对复杂的事物进行分类,然后对各个分类下的细节进行面向过程的思索。(面向对象适合处理复杂、需要多人协作的问题)
对于描述复杂的事物,为了从宏观上把握、从整体上合理分析,我们需要使用面向对象的思路来分析整个系统。但是,具体到微观操作,我们仍然需要面向过程的思路去处理。
二、何为面向对象
1.面向对象的本质
以类的方式组织代码,以对象的方式封装数据
以类的方式组织代码,以对象的方式封装数据
以类的方式组织代码,以对象的方式封装数据
2.抽象的概念
将事物抽象到一类
将事物抽象到一类
将事物抽象到一类
3.三大特性
封装、继承、多态
封装、继承、多态
封装、继承、多态
4.从认识的角度看待'面向对象'
是先有对象后有类。(对象是具体的事物。类是抽象的,是对对象的抽象)
5.从代码运行的角度看待
是先有类后有对象。(类是对象的模板)
三、方法回顾&深入
1.break,continue,return
-
break:结束循环,也可以用来跳出switch。
-
continue:结束本次循环,继续下一次循环。
-
return:结束方法,return之后的代码不生效。
2.异常抛出
后续讲解
3.静态方法&非静态方法
-
静态方法不能调用非静态方法。
-
非静态方法可以调用静态方法。
-
静态方法在类加载时加载,此时还没有非静态方法,不能去调用不存在的方法。
4.值传递&引用传递
-
引用传递本质还是值传递
-
值传递是指在调用方法时将实际参数 复制一份传递到方法中,这样在方法中如果对参数进行修改将不会影响到实际参数。
-
引用传递就是直接把内存地址传递过去,也就是说引用传递时,操作的其实是数据源这样的话修改会影响引用对象的源数据。
5.this 关键字
-
this关键字代表对象的本身。
-
后面讲到继承时讲解。
四、类&对象
1.类&对象的关系
类:一种抽象的概念,它是对某一类事物整体的描述/定义,但其不能代表一个具体的事物。
Ex:
-
动物、植物、手机、电脑等
-
Person类,Pet类,Car类等,这些类都是用来描述、定义某一具体事物应该具有的特点和行为。
对象:是抽象概念的具体实例。
Ex:
-
能够体现出特点、展现出功能的具体的实例、而不是一个抽象的概念。
-
张三——Person类的具体实例。
2.创建和初始化对象
-
new 关键字
使用new关键字创建对象时,除了分配内存空间之外,还会给创建好的对象进行默认的初始化以及对类中构造器的调用。
-
构造器
构造器,也称为构造方法,是在进行创建对象的时候必须要调用的。
-
构造器的特点
1.必须和类的名字相同。
2.必须没有返回类型,也不能写void。
-
构造器的作用
1.new的本质是在调用构造方法。(类默认会有一个隐式的无参构造)。
2.初始化对象的值(可以定义有参构造初始化对象的属性值)。
-
注意点
1.定义有参构造后,若想使用无参构造器,必须要显示定义一个无参的构造。
2.IDEA快捷键Alt+Ins
-
五、创建对象内存分析
六、类&对象总结
1.类与对象
类是一个模板——抽象
对象是一个具体的实例
2.方法
定义、调用!
3. 对应的引用
引用类型:基本类型(8)
对象是通过引用来操作的:栈——>堆
4.属性:字段Field 成员变量
默认初始化:
-
数字:0 0.0
-
char: u0000
-
boolean:false
-
引用:null
万能公式: 修饰符 属性类型 属性名 = 属性值
万能公式: 修饰符 属性类型 属性名 = 属性值
万能公式: 修饰符 属性类型 属性名 = 属性值
5.对象的创建和使用
-
必须使用 new 关键字创造对象, 构造器 Person kuangshen = new Person();
-
对象的属性 kuangshen.name
-
对象的方法 kuangshen.sleep()
6.类
静态的属性 属性
动态的行为 方法
七、 Java的三代特性
1.封装
——数据的隐藏,隐藏对象的具体实现细节,对外提供统一的访问接口。
-
高内聚、低耦合
高内聚:类内部数据操作细节由自己完成,不允许外部干涉。
低耦合:仅暴露少量的方法给外部使用。
-
封装
禁止直接访问一个对象中数据的实际表示,而应该通过操作接口来访问(数据的隐藏)
-
属性私有
get、set方法
封装的作用
-
提高程序的安全性,保护数据。
-
隐藏代码的实现细节。
-
统一接口,get、set。
-
增加系统的可维护性。
2.继承(Ctril+H)
继承的本质是对某一批类的抽象,从而实现对现实世界更好的建模。
-
extends的意思为拓展,子类是父类的拓展。
-
Java中类只有单继承,没有多继承,但类可以多重继承。
-
继承是类与类之间的关系,除此之外,类和类之间的关系还有依赖、组合、聚合等。
-
子类和父类之间,从意义上讲应该有‘is a’的关系。
-
子类继承父类就会拥有父类的全部方法。(私有方法除外)
Object类
-
object类是所有类的基类。
-
所有的类都默认直接或间接继承Object类。
Super类
-
super调用父类的构造方法,必须在构造方法的第一个。
-
super必须只能出现在子类的方法或子类的构造方法中。
-
super和this不能同时调用构造方法,因为他们调用构造方法时都要求放在构造方法的第一行。
-
new 对象时,首先执行父类的构造方法。
super和this的比较
this | super | |
---|---|---|
代表的对象不同 | 代表本身调用者这个对象 | 代表父类对象的引用 |
使用前提 | 没有继承也可以使用 | 只能在继承条件下才使用 |
构造方法 | 调用本类的构造方法 | 调用父类的构造方法 |
3.方法重写——多态
-
重写都是方法的重写,和属性无关。
-
需要有继承关系,子类重写父类的方法。
-
方法名必须相同;参数列表也必须相同。
-
修饰符:重写之后的方法修饰符的范围可以扩大但不能缩小。
public > protected > default > private
-
抛出异常:重写之后的方法抛出异常的范围可以被缩小,但不能扩大。
ClassNotFoundException < Exception
重写的作用
-
父类的功能,子类不一定需要,或者不一定满足。
-
Alt+Ins快捷键,
方法重写的注意点
-
静态方法:方法的调用只和左边变量有关,和定义的数据类型无关。
// B是A的父类,A类和B类都有静态方法test();
B b = new A()
b.test();// 调用父类的test() -
非静态方法才是重写。
-
子类的对象指向父类的引用时,子类和父类都有同一个方法,则子类重写了父类的方法,则会调用子类的方法。
对象执行那些方法,主要是看左边的类型,和右边的关系不大。
// B是A的父类,A类和B类都有方法test();
B b = new A();// 子类的对象指向父类的引用
b.test();// 子类重写父类的方法,则调用子类的test()。
-
子类A可以调用自己的或者继承父类的方法。
-
父类B可以指向子类,但是不能调用子类独有的方法。
-
父类B调用子类A独有的方法时可以进行对象强制类型转换。
4.多态
-
同一个方法,可以根据发送对象的不同而采用多种不同的行为方式。
-
一个对象的实际类型是确定的,但是他可以指向对象类型的引用有很多。(父类,有关系的类)
多态的注意点
-
多态是方法的多态,属性没有多态。
-
子类和父类有联系,继承关系,涉及类型转换异常ClassCasException
-
多态存在的条件:
-
继承关系
-
方法需要重写
-
父类引用指向子类对象
-
-
不能被重写的方法:
-
静态方法属于类,不属于实例,不能重写。
-
final修饰的方法,不能重写。
-
private修饰的方法,不能重写。
-
八、instance of & 类型转换
1.instance of
-
X instanceof Y 的编译能不能通过,可以体现出X和Y是否有关系。
-
public static void main(String[] args) {
// Object>String
// Object>Person>Teacher
// Object>Person>Student
Object s1 = new Student();
System.out.println(s1 instanceof Student);//true
System.out.println(s1 instanceof Person);//true
System.out.println(s1 instanceof Object);//true
System.out.println(s1 instanceof Teacher);//false
System.out.println(s1 instanceof String);//false
Person s2 = new Student();
System.out.println(s2 instanceof Student);//true
System.out.println(s2 instanceof Person);//true
System.out.println(s2 instanceof Object);//true
System.out.println(s2 instanceof Teacher);//false
//System.out.println(s2 instanceof String);//编译报错
Student s3 = new Student();
System.out.println(s3 instanceof Student);//true
System.out.println(s3 instanceof Person);//true
System.out.println(s3 instanceof Object);//true
//System.out.println(s3 instanceof Teacher);//编译报错
//System.out.println(s3 instanceof String);//编译报错
}
2.类型转换
-
子类-->父类,向上转型。
-
父类-->子类,向下转型;强制转换。
-
方便方法的调用,减少重复的代码。
九、static 关键字讲解
-
静态变量
-
对于类而言
在内存中只有一个,能被类中所有的实例共享。
-
-
静态属性&静态方法可以通过类名调用
-
静态方法不能调用非静态方法,非静态方法肯伊调用静态方法。
-
匿名代码块
-
在创建对象时自动创建,并在构造器之前,可以用来初始化赋值。
-
静态代码块和类一起加载,但只在类中执行一次;
-
-
创建对象调用的顺序
-
静态代码块 >匿名代码块 >构造方法
-
// person类
public class Person {
// 2:第二个执行,在创建对象时自动执行,并且在构造器之前执行
{
System.out.println("Person匿名代码块");
}
// 1:第一个执行,只在类加载的时候执行一次
static{
System.out.println("Person静态代码块");
}
// 3:第三个执行
public Person() {
System.out.println("Person无参构造");
}
}
************************************************
public class Main {
public static void main(String[] args) {
Person p1 = new Person();
System.out.println("******************");
Person p2 = new Person();
}
}
// 打印
Person静态代码块
Person匿名代码块
Person无参构造
******************
Person匿名代码块
Person无参构造
-
继承关系创建子类对象时
-
先执行父类静态代码块再执行子类静态代码块
-
然后执行父类匿名代码块、父类的构造方法
-
最后执行子类的匿名代码块,子类的构造方法
-
// person类
public class Person {
// 2:第二个执行,在创建对象时自动执行,并且在构造器之前执行
{
System.out.println("Person匿名代码块");
}
// 1:第一个执行,只在类加载的时候执行一次
static{
System.out.println("Person静态代码块");
}
// 3:第三个执行
public Person() {
System.out.println("Person无参构造");
}
}
************************************************
// student类
public class Student extends Person {
{
System.out.println("Student匿名代码块");
}
static{
System.out.println("Student静态代码块");
}
public Student() {
System.out.println("Student无参构造");
}
}
************************************************
public class Main {
public static void main(String[] args) {
Student s1 = new Student();
System.out.println("******************");
Student s2 = new Student();
}
}
// 打印
Person静态代码块
Student静态代码块
Person匿名代码块
Person无参构造
Student匿名代码块
Student无参构造
******************
Person匿名代码块
Person无参构造
Student匿名代码块
Student无参构造
静态导入包
import static java.lang.Math.random;
System.out.println(random());// 静态导入后可以直接使用
十、抽象类
-
abstract关键字修饰的类是抽象类。
-
抽象方法必须放在抽象类中。
-
抽象类中可以写普通方法。
-
抽象类不能new,只能靠子类去实现。
-
抽象类是抽象的抽象:约束。
-
抽象类的局限性是Java只能单继承。
-
抽象类的所有抽象方法,继承了它的子类,都必须要实现他的抽象方法,除非它的子类也是抽象类,则由它的子子类去实现。
抽象类思考问题
-
抽象类有没有构造方法? 答:抽象类有构造方法,但是不能直接创建其实例对象;实例化子类时,需要先初始化父类(调用父类的构造方法)。
-
抽象类存在的意义? 答:抽象类是对类的抽象。
十一、接口
-
接口是只有规范,自己无法写方法,是专业的约束;约束和实现分离:面向接口编程。 普通类只有具体实现;抽象类具体实现和规范都有。
-
接口就是规范,定义了一组规则;体现了现实世界中“如果你是…则必须能…”。
-
OO的精髓,对对象的抽象,最能体现这一点的就是接口;我们讨论设计模式只针对具备抽象能力的语言(比如C++,C#,Java),设计模式研究的实际上就是如何合理的去抽象。
-
声明接口的关键字是interface。
接口的作用
-
接口是约束。
-
接口定义了一些方法,让不同的人去实现。
-
接口中变量的修饰默认都是public static final
-
接口中方法的修饰默认都是public abstract
-
接口不能被实例化,接口没有构造方法。
-
implements可以实现多个接口。
-
接口的方法必须要重写。
十二、内部类
-
内部类就是在一个类的内部再定义一个类
-
成员内部类:可以获得外部类的私有属性和私有方法。
-
静态内部类:可以获得外部类的静态的私有属性和静态的私有方法。
-
局部内部类:在方法内再定义一个类。
-
匿名内部类:没有名字初始化类,不用将实例保存到变量中。
十三、总结
1.举例说明抽象类和接口的区别
-
男人、女人是两个类,那他们的抽象类是人;说明他们是人。抽象类表示的是这个对象是什么。
-
人可以“吃东西”,动物也可以“吃东西”,可以把“吃东西”定义成一个接口,让人的类或动物的类去实现这个接口;接口表示的是这个对象能做什么。
2.抽象类和接口的区别
-
抽象类是对根源的抽象,接口是对动作的抽象。
-
接口可以支持回调,继承并不能回调。
-
一个类依次可以实现多个接口,但是只能继承一个父类。
在高级语言中,一个类只能继承一个类(抽象类)(人不可能同时是生物和非生物),但是可以实现