目录
2.2.1 四种访问权限修饰符(public、default、protected、private)
课程链接:https://www.bilibili.com/video/BV1Kb411W75N?p=176&spm_id_from=pageDriver
序、面向过程与面向对象
0.1 基本概念
二者都是一种思想,面向对象是相对于面向过程而言的。
- 面向过程,强调的是功能行为,以函数为最小单位,考虑怎么做。
- 面向对象,将功能封装进对象,强调具备了功能的对象,以类/对象为最小单位,考虑谁来做。
面向对象更加强调运用人类在日常的思维逻辑中采用的思想方法与原则,如抽象、分类、继承、聚合、多态等。
0.2 例子——“人把大象装进冰箱”
1.面向过程: 强调的是功能行为,以函数为最小单位,考虑怎么做。
- ①把冰箱门打开
- ②抬起大象,塞进冰箱
- ②把冰箱门关闭
2.面向对象: 强调具备了功能的对象,以类/对象为最小单位,考虑谁来做。
人{
打开(冰箱){
冰箱.开开() ;
}
抬起(大象){
大象.进入(冰箱);
}
关闭(冰箱){
冰箱.闭合();
}
}
冰箱{
开开(){}
闭合(){}
}
大象{
进入冰箱(){}
}
0.3 面向对象的思想概述
程序员从面向过程的执行者转化成了面向对象的指挥者
面向对象分析方法分析问题的思路和步骤:
- ➢根据问题需要,选择问题所针对的现实世界中的实体。
- ➢从实体中寻找解决问题相关的属性和功能,这些属性和功能就形成了概念世界中的类。
- ➢把抽象的实体用计算机语言进行描述,形成计算机世界中类的定义。即借助某种程序语言,把类构造成计算机能够识别和处理的数据结构。
- ➢将类实例化成计算机世界中的对象。对象是计算机世界中解决问题的最终工具。
0.4 面向对象的三大特征
- ➢封装(Encapsulation)
- ➢继承(Inheritance)
- ➢多态(Polymorphism)
一、Java类及类的成员
1.1 类
类(Class)和对象(Object)是面向对象的核心概念。
- ➢类是对一类事物的描述,是抽象的、概念上的定义
- ➢对象是实际存在的该类事物的每个个体,因而也称为实例(instanlce)。
1.2 类的成员
- ➢属性:对应类中的成员变量
- ➢行为:对应类中的成员方法
1.3 对象的内存解析
1. 堆(Heap),此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。这一点在Java虚拟机规范中的描述是: 所有的对象实例以及数组都要在堆上分配。
2. 栈(Stack) ,是指虚拟机栈。虚拟机栈用于存储局部变量等。局部变量表存放了编译期可知长度的各种基本数据类型(boolean、byte、char、short、int、float、long、double)、对象引用(reference类型,它不等同于对象本身,是对象在堆内存的首地址)。方法执行完, 自动释放。
3. 方法区(Method Area),用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据
上图中的虚拟机栈,即为平时提到的栈结构。
- 局部变量存储在栈结构中
- 堆,我们将new出来的结构(比如:数组、对象)加载在对空间中。补充:对象的属性(非static的) 加载在堆空间中。
方法区:类的加载信息、常量池、静态域
编译完源程序以后,生成一一个或多个字节码文件。我们使用Jvm中的类的加载器和解释器对生成的字节码文件进行解释运行。意味着,需要将字节码文件对应的类加载到内存中,涉及到内存解析。
二、面向对象的三大特征
封装性、继承性、多态性
2.1 理解”万事万物皆对象“
在Java语言范畴中,我们都将功能、结构等封装到类中,通过类的实例化,来调用具体的功能结构
2.1.1 方法重载
定义: 在同一个类中,允许存在一个以上的同名方法,只要它们的参数个数或者参数类型不同即可。
2.1.2 可变函数的形参
JavaSE 5.0中提供了Varargs(variable number of arguments)机制,允许直接定义能和多个实参相匹配的形参。从而,可以用一种更简单的方式,来传递个数可变的实参。
//JDK 5.0以前:采用数组形参来定义方法,传入多个同一类型变量
public static void test(int a ,String[] books);
//JDK5.0:采用可变个数形参来定义方法,传入多个同一-类型变量
public static void test(int a ,String...books);
使用方式
- 可变个数形参的格式: 数据类型...变量名
- 当调用可变个数形参的方法时,传入的参数个数可以是: 0个,1个, 2个,。。
- 可变个数形参的方法与本类中方法名相同,形参不同的方法之间构成重载
- 可变个数形参的方法与本类中方法名相同,形参类型也相同的数组之间,不构成重载。
- 可变个数形参在方法的形参中,必须声明在末尾
- 可变个数形参在方法的形参中,最多只能声明一个可变形参。
2.1.3 方法的参数传递机制——值传递(只有一种)
- 形参:方法定义时,声明的小括号内的参数
- 实参:方法调用时,实际传递给形参的数据
Java的方法参数传递只有一种,就是 “pass-by-value”,也就是值传递。
- 如果是基本类型,就是将原有的数据拷贝一份,方法内的操作对原有的数据不会有影响。
- 如果是对象类型,这里是容易误解的地方,因为正好规定对象的地址也叫做"reference", 我们将对象作为参数传递的时候实际上是将对象的地址传递进去。
如果参数是基本数据类型,此时实参赋给形参的是,实参真实存储的数据值。
如果参数是引用数据类型,此时实参赋给形参的是实参存储数据的地址值。
2.2 面向对象特征:封装与隐藏
我们程序设计追求“高内聚,低耦合
- ➢高内聚:类的内部数据操作细节自己完成,不允许外部干涉;
- ➢低耦合:仅对外暴露少量的方法用于使用。
隐藏对象内部的复杂性,只对外公开简单的接口。便于外界调用,从而提高系统的可扩展性、可维护性。通俗的说,把该隐藏的隐藏起来,该暴露的暴露出来。这就是封装性的设计思想。
2.2.1 四种访问权限修饰符(public、default、protected、private)
对于class的权限修饰只可以用public和default(缺省)。
- ➢public类可以在任意地方被访问。
- ➢default类只可以被同一个包内部的类访问。
2.3 继承
Java中关于继承性的规定:
- 1.一个类可以被多个子类继承。
- 2.Java中类的单继承性: 一个类只能有一个父类
- 3.子父类是相对的概念。
- 4.子类直接继承的父类,称为:直接父类。间接继承的父类称为:间接父类
- 5.子类继承父类以后,就获取了直接父类以及所有间接父类中声明的属性和方法
- 如果我们没有显式的声明一个类的父类的话,则此类继承于java. lang . Object类
- 所有的java类 (除java.lang . object类之外)都直接或间接的继承于java . lang. object类。意味着,所有的java类具有java.lang . object类声明的功能。
2.3.1 方法的重写
●定义: 在子类中可以根据需要对从父类中继承来的方法进行改造,也称为方法的重置、覆盖。在程序执行时,子类的方法将覆盖父类的方法。
●要求:
- 1.子类重写的方法必须和父类被重写的方法具有相同的方法名称、参数列表
- 2.子类重写的方法的返回值类型不能大于父类被重写的方法的返回值类型
- 3. 子类重写的方法使用的访问权限不能小于父类被重写的方法的访问权限。子类不能重写父类中声明为private权限的方法
- 4.子类方法抛出的异常不能大于父类被重写方法的异常
● 注意
子类与父类中同名同参数的方法必须同时声明为非static的(即为重写),或者同时声明为static的(不是重写)。因为static方法是属于类的,子类无法覆盖父类的方法。
2.3.2 对比重载和重写
- 对于重载而言,在方法调用之前,编译器就已经确定了所要调用的方法,这称为“早绑定”或“静态绑定”;
- 对于多态,只有等到方法调用的那一刻,编译器才会确定所要调用的具体开法,这称为“晚绑定”或“动态绑定”。
重写方法的规则:
- 1)、参数列表必须完全与被重写的方法相同,否则不能称其为重写而是重载。
- 2)、返回的类型必须一直与被重写的方法的返回类型相同,否则不能称其为重写而是重载。
- 3)、访问修饰符的限制一定要大于被重写方法的访问修饰符(public>protected>default>private)
- 4)、重写方法一定不能抛出新的检查异常或者比被重写方法申明更加宽泛的检查型异常
重载的规则:
- 1)、必须具有不同的参数列表;
- 2)、可以有不同的返回类型,只要参数列表不同就可以了;
- 3)、可以有不同的访问修饰符;
- 4)、可以抛出不同的异常;
2.3.2子类对象实例化的过程
1.从结果上来看: (继承性)
子类继承父类以后,就获取了父类中声明的属性或方法。创建子类的对象,在堆空间中,就会加载所有父类中声明的属性。
2.从过程上来看
当我们通过子类的构造器创建子类对象时,我们一定会直接或间接的调用其父类的构造器,进而调用父类的父类的构造器,直到调用了java. lang.Object类中空参的构造器为止。正因为加载过所有的父类的结构,所以才可以看到内存中有父类中的结构,子类对 象才可以考虑进行调用。
明确:虽然创建子类对象时,调用了父类的构造器,但是自始至终就创建过一 个对象,即为new的子类对象。
2.4 多态性
1.理解多态性: 可以理解为一个事物的多种形态。
2.何为多态性: 对象的多态性:父类的引用指向子类的对象(或子类的对象赋给父类的引用)
3.多态的使用:虚拟方法调用
有了对象的多态性以后,我们在编译期,只能调用父类中声明的方法,但在运行期,我们实际执行的是子类重写父类的方法。
2.4.1 虚方法调用
●正常的方法调用
Person e = new Person();
e.getlnfo();
Student e = new Student();
e.getlnfo();
●虚拟方法调用(多态情况下)
子类中定义了与父类同名同参数的方法,在多态情况下,将此时父类的方法称为虚拟方法,父类根据赋给它的不同子类对象,动态调用属于子类的该方法。这样的方法调用在编译期是无法确定的。
Person e = new Student();
e.getlnfo(); //调用Student类的getInfo()方法
●编译时类型和运行时类型
编译时e为Person类型,而方法的调用是在运行时确定的,所以调用的是Student类的getlnfo()方法。一动态绑定
2.5 object类
2.5.1 java.lang.object类
1. object类是所有Java类的根父类
2.如果在类的声明中未使用extends关键字指明其父类,则默认父类为java. lang . object类
3. Object类中的功能(属性、方法)就具有通用性。
- 属性:无
- 方法: equals() / toString() / getClass() /hashCode() / clone() / finalize( )wait()、notify()、 notifyAll()
4. object类只声明了一个空参的构造器
2.5.2 ==和equals的区别
== : 运算符
- 1.可以使用在基本数据类型变量和引用数据类型变量中
- 2.如果比较的是基本数据类型变量: 比较两个变量保存的数据是否相等。(不一 定类型要相同)。如果比较的是引用数据类型变量: 比较两个对象的地址值是否相同.
equals( )方法的使用:
- 1.是一个方法,而非运算符
- 2.只能适用于引用数据类型
- 3. Object类中equals( )的定义:
public boolean equals(Object obj) {
return (this == obj);
}
说明: object类中定义的equals( )和==的作用是相同的:比较两个对象的地址值是否相同.即两个引用是否指下
- 4.像String、 Date、File、包装类等都重写了object类中的equals()方法。重写以后,比较的不是两个引用的地址是否相同,而是比较两个对象的"实体内容"是否相同。
面试题,比较==和equals
- 1 == 既可以比较基本类型也可以比较引用类型。对于基本类型就是比较值,对于引用类型就是比较内存地址
- 2 equals的话, 它是属于java.lang.Object类里面的方法,如果该方法没有被重写过默认也是==
- 3具体要看自定义类里有没有重写Object的equals方法来判断。通常情况下, 重写equals方法,会比较类中的相应属性是否都相等。
2.5.3 toString方法
- toString()方法在Object类中定义,其返回值是String类型,返回类名和它的引用地址。
- 在进行String与其它类型数据的连接操作时,自动调用toString()方法
Date now=new Date();
System.out.printIn("now="+now);相当于
System.out.printIn("now="+now.toString());
- 可以根据需要在用户自定义类型中重写toString()方法。如String类重写了toString()方法,返回字符串的值。
s1="hello";
System.out.println(s1);//相当于System.out.println(s1.toString());
- 基本类型数据转换为String类型时,调用了对应包装类的toString()方法
int a=10;
system.out.println("a="+a);
2.6 包装类 wrapper 的使用
Java语言是一个面向对象的语言,但是Java中的基本数据类型却是不面向对象的,这在实际使用时存在很多的不便,为了解决这个不足,在设计类时为每个基本数据类型设计了一个对应的类进行代表,这样八个和基本数据类型对应的类统称为包装类(Wrapper Class),有些地方也翻译为外覆类或数据类型类
Java中的包装器类有两个主要的目的:
- 提供一种机制,将基本值“包装”到对象中,从而使基本值能够包含在为对象而保留的操作中,比如添加到Collections 中,或者从带对象返回值的方法中返回。注意,java5增加了自动装箱和拆箱,程序员过去需手工执行的许多包装操作,现在可以由java自动处理了。
- 为基本值提供分类功能。这些功能大多数于各种转换有关:在基本值和String对象间相互转换,在基本值和String对象之间按不同基数转换,如二进制、八进制和十六进制。
装箱就是自动将基本数据类型转换为包装器类型;拆箱就是自动将包装器类型转换为基本数据类型。
nteger i = 10; //装箱 int index = i; //拆箱
2.7 代码块
1.代码块的作用:用来初始化类、对象
2.代码块如果有修饰的话,只能使用static.
3.分类:静态代码块vs非静态代码块
静态代码块
- >内部可以有输出语句
- >随着类的加载而执行,而且只执行一-次
- >作用:初始化类的信息
- >如果一个类中定义了多个静态代码块,则按照声明的先后顺序执行
- >静态代码块的执行要优先于非静态代码块的执行
- >静态代码块内只能调用静态的属性、静态的方法,不能调用非静态的结构
class Person {
public static int total;
static {
total = 100;
System. out. println("in static block!");
}
}
public class PersonTest {
public static void main(string[] args) {
System. out . println("total ="+ Person. total);
System. out . println("total ="+ Person. total);
}
}
非静态代码块
- >内部可以有输出语句
- >随着对象的创建而执行
- >每创建一个对象,就执行一次非静态代码块
- >作用:可以在创建对象时,对对象的属性等进行初始化
- >如果一一个类中定义了多个非静态代码块,则按照声明的先后顺序执行
- >非静态代码块内可以调用静态的属性、静态的方法,或非静态的属性、非静态的方法
三、其他关键字
3.1 instanceof关键字
a instanceof A
判断对象a是否是类A的实例。如果是,返回true;如果不是,返回false。
使用情境:为了避免在向下转型时出现ClassCastException的异常,我们在向下转型之前,先进行instanceof的判断,一旦返回true, 就进行向下转型。如果返回false,不进行向下转型。
3.2 static关键字
当我们编写一个类时,其实就是在描述其对象的属性和行为,而并没有产生实质上的对象,只有通过new关键字才会产生出对象,这时系统才会分配内存空间给对象,其方法才可以供外部调用。
我们有时候希望无论是否产生了对象或无论产生了多少对象的情况下,某些特定的数据在内存空间里只有一份,例如所有的中国人都有个国家名称,每一个中国人都共享这个国家名称,不必在每一个中国人的实例对象中都单独分配一个用于代表国家名称的变量。
1. static :静态的
2. static可以用来修饰:属性、方法、代码块、内部类
3.使用static修饰属性: 静态变量
属性,按是否使用static修饰,又分为:静态属性Vs非静态属性(实例变量)
- 实例变量: 我们创建了类的多个对象,每个对象都独立的拥有一套类中的非静态属性。当修改其中一一个对象中的非静态属性时,不会导致其他对象中同样的属性值的修改。
- 静态变量: 我们创建了类的多个对象,多个对象共享同一个静态变量。当通过某T个对象修改静态变量时,会导致其他对象调用此静态变量时,是修改过了的。
3.3 final关键字
- 1. final可以用来修饰的结构: 类、方法、变量
- 2. final用来修饰一个类:此类不能被其他类所继承。比如: String类、System类、StringBuffer类
- 3. final用来修饰方法: 表明此方法不可以被重写。比如: object类中getClass();
- 4. final 用来修饰变量:此时的"变量"就称为是一个常量
四、扩展知识
4.1 java bean
● JavaBean是一种可重用组件。
● 所谓javaBean,是指符合如下标准的Java类:
- ➢类是公共的
- ➢有一个无参的公共的构造器
- ➢有属性,且有对应的get、set方法
● 用户可以使用JavaBean将功能、处理、值、数据库访问和其他任何可以用Java代码创造的对象进行打包,并且其他的开发者可以通过内部的JSP页面、Servlet、 其他JavaBean、applet程序或者 应用来使用这些对象。用户可以认为JavaBean提供了一种 随时随地的复制和粘贴的功能,而不用关心任何改变。
4.2 mvn的设计模式
MVC是常用的设计模式之一,将整个程序分为三个层次:视图模型层,控制器层,与数据模型层。这种将程序输入输出、数据处理,以及数据的展示分离开来的设计模式使程序结构变的灵活而且清晰,同时也描述了程序各个对象间的通信方式,降低了程序的耦合性。
4.2.1 模型层model 主要处理数据
- >数据对象封装model bean/domain
- >数据库操作类 model. dao
- >数据库 model.db
4.2.2 控制层controller 处理业务逻辑
- >应用界面相关controller activity
- >存放fragment controller.fragment
- >显示列表的适配器controller adapter
- >服务相关的controller. service
- >抽取的基类controller.base
4.2.3 视图层 view显示数据
- >相关工具类view.utils
- >自定义view view.ui