面向对象
面向对象是一种思考问题的方式,以对象的形式来思考问题
类:是对象描述 ,类是对象的抽象(抽象:提取对象的共性)
对象:是实实在在存在的个体,它是类具体实现,也叫做类的实例
对象创建的过程(new 类名()),叫做对象的实例化
类的定义:
[修饰符] class 类名
{
构造器 //对应的是对象的创建方式
成员变量 //对应的是对象的属性
成员方法 //对应的是对象的行为(功能)
}
构造器(构造方法,构造函数):
如果不提供有参数的构造器,jvm会提供一个默认的无参构造器
[修饰符] 类名()
{
方法体
}
如果类中提供了有参构造器,则jvm就不再提供无参构造器,如果需要使用无参构造,则需要自己定义
有参构造器
[修饰符] 类名(参数数据类型 参数名...)
{ }
如果一个类中同时存在,无参构造器和多个有参构造器,这个叫做构造器的重载
成员变量:
存在于类中,但是处于成员方法以外
作用域: 从声明的地方开始,到类的结束
成员变量是有默认值(缺省值)的,根据数据类型的不同,初始值是不同,如果是int类型的, 初始值是0 ,如果是引用类型,初始是null
成员变量,可以用修饰符修饰
局部变量:
存在于成员方法中,注意:参数是特殊的局部变量
作用域:从声明的地方开始,到方法的结束
局部变量没有默认值
只能用final修饰
成员方法:
[修饰符] void|返回值的数据类型 方法名([参数类型 参数名 , ...])
{
方法体 也叫作代码块
}
对象的创建和使用
对象的创建
类名 对象名 = new 类名([参数,...]);
对象的使用
获得对象的属性
数据类型 变量名 = 对象名.属性名
修改对象的属性
对象名.属性名 = 属性值 ;
调用对象的方法
对象名.方法名();
方法的重载
1,在同一个类中
2,方法名相同
3,参数不同:参数个数,参数顺序,参数类型 (满足其中之一,则视为参数不同)
this关键字的使用
每一个类中都有两个特殊的成员变量,一个是this,一个是super
this 里面存储的当当前对象的地址 ,代表就是当前对象
this有两个用法:
1,当成员变量名和局部变量名发生冲突的时候,可以使用 this.变量名 标注成员变量
2,当一个构造器需要调用本类的其他构造器时,可以使用this()进行调用,但是this()必须写在构造器方法体的第一行
static(静态的)是修饰符,可以用来修饰成员变量和成员方法
static 修饰成员变量
有static修饰的成员变量叫做类变量 也叫做 类成员变量 也叫做静态变量
没有static修饰的成员变量 叫做实例变量 这里的实例指的是对象
有static修改的成员变量,是所有对象共有的变量
使用及修改需要 用类名.变量名
static 修饰成员方法
有static修饰的成员方法叫做类方法,也叫做静态方法
没有static修饰的成员方法叫做实例方法 这里的实例指的是对象
有static修饰的成员方法是所有该类对象共有的方法
调用的时候,可以使用对象名.方法名(); 也可以使用类名.方法名();
java程序的运行,首先jvm将class文件加载到jvm中,这时会同时把静态变量和静态方法同时加载到jvm
当创建该类对象的时候,jvm才会加载实例变量和实例方法
静态方法可以访问静态变量和静态方法,但是不能访问实例变量和实例方法
实例方法可以访问静态方法和静态变量也可以访问实例方法和实例变量 即 实例方法可以访问类中所有的变量及方法
static 修饰代码块
代码块:一般用作初始化工作
{ 代码 }
有static修饰的代码块,叫静态代码块,一般用于初始化一些静态的变量
静态代码块,在class文件被加载时执行,程序运行期间,只会执行一次
当第一次创建对象的时候,执行顺序是
先加载class文件,然后是按照顺序 加载静态变量,静态方法,静态代码块(这里的顺序指的是源文件的编码的顺序)
然后会执行一次静态代码块
然后按照顺序 执行实例代码块
创建对象的时候是先执行实例代码块再执行构造器
没有static修饰的代码块,叫做实例代码块,一般用于初始化工作
实例代码块,每次创建对象时,都会执行一次
引用:
Person p = new Person() ;
这个p就是一个引用数据,其实p里存的不是真正的对象,而是对象在内存中的地址
Java中的内存 栈 堆 方法区
栈中的数据:如果是基本数据类型,则存储的是数据
如果是引用数据类型,则存储的是地址
所有的方法的运行都是在栈中,每运行一个方法,jvm就会在栈内存开辟一个空间,用来存储方法中的变量
引用数据类型,在栈中存储的是一个地址,这个地址指向的是对象在堆内存中的实际位置
每创建一个新的对象,jvm就会在堆内存中去开辟一个空间,存放该对象的属性,而方法存在于方法区
Java中的引用数据类型有哪些?
数组,类,接口
思考:数组中数,存在哪? //在堆内存中
int a = {1,2,3,4,5,6} ;
栈内存中的a的值是什么? 是地址 指的是数组中的数在堆内存中的实际的位置
引用
Person p = new Person() ;
p 中存储的是对象在内存中的地址
程序运行过程中,一旦新建对象,那么该对象时存储在堆内存中
方法的运行都是在栈内存中,每运行一个方法,jvm就会在栈内存中开辟一个空间,用于存储该方法运行时产生的变量
如果变量的数据类型是基本数据类型 则存储的是真实数据
如果变量的数据类型是引用数据类型 则存储的是数据在堆内存中的地址
this 关键字
Java的类中有两个特殊的成员变量,一个是this,代表当前对象的引用,this中存放的是当前对象的地址
另一个是super 代表的是当前对象的父类对象 super中存放的是当前对象的父类对象在堆内存中的地址
this关键字的作用:
1,当类中的成员变量和局部变量重名时,可以通过this.变量名来标注成员变量
2,当一个构造器需要调用类中其他的构造器时,可以使用this([参数...])来进行调用
注意:构造器只能被构造器所调用,不能再成员方法中调用构造器
如果一个构造器需要调用另一个构造器,则this([参数....])必须位于构造器方法体中的第一行
static关键字 就是一个修饰符 可以用来修饰成员变量,成员方法,代码块,类
static修饰成员变量
有static修饰的成员变量叫类变量 也叫做 静态变量 是该类所有对象共享的变量 调用方法推荐使用类名.变量名
没有static修饰的成员变量叫做实例变量 这里的实例指的是对象
static修饰成员方法
有static修饰的成员方法叫做类方法,也叫做静态方法,是该类所有对象共享的方法 ,调用 推荐使用 类名.方法名([参数...]);
没有static修饰的成员方法叫做实例方法,调用 对象名.方法名([参数....]);
static修饰代码块
有static修饰的代码块叫做静态代码块,主要就是用来做一些初始化工作,比如初始化静态变量
在程序运行的整个过程中,只会执行一次
没有static修饰的代码块叫做实例代码块,主要用于一些初始化的工作,比如初始化实例变量
每创建一个对象,就会执行一次
实例代码块和构造器谁先执行? 代码块先执行
注意:
1,静态代码块,静态方法只能访问静态变量,静态方法,不能访问实例方法,实例变量
2,实例方法,实例代码块 可以访问该类中所有的方法及变量
jvm类加载流程
程序运行时,是先加载class文件,同时加载的还有该class文件中的静态变量,静态方法,静态代码块
当创建对象时,jvm才会分配空间,加载实例变量,实例方法,实例代码块
在整个程序运行的过程中,一个class文件只会被加载一次
包:是Java语言当中用来管理类,接口等源文件的一个管理工具。
包的使用和声明:
包的声明:
package 包名;
1,包名一般采用多级包名;package com ; 一级包名 package com.zdsoft; 二级包名
2,包名一般使用小写字母
3,包名不能以java和javax开头
4,一般情况主包名采用的是倒置的域名+项目名称+功能名称 比如:com.huawei.netopen.util com.zdsoft.qq.login
5,包的声明语句必须位于源文件的第一行
包的导入:
什么时候需要导入包?
当一个包里面的类需要引用另外一个包里面的类时,就需要导入 关键字 import
语法:
import 包名.类名|接口名; //这是导入指定包中的指定的类 或者指定的接口名
import 包名.* ; //这是导入指定包中的所有的类和接口
注意:导包语句写在源文件 声明包名之后,声明类之前;
访问权限修饰符
private 修饰的成员方法和成员变量不能被其他类访问,本类中可以访问
也就是说,如果你在其他的类中创建了该类对象,那么,这个对象是不能调用以private修饰的所有的成员方法和变量
(default) 如果成员变量和成员方法前面没有访问权限修饰符 则 默认为default
被default修饰的成员变量和成员方法,只能被本类和与其在同一个包中的其他类访问
protected 被该修饰符修饰的成员变量和成员方法可以被本类和与其在同一个包中的其他类以及不与其在同一个包中的子类访问
public 被该修饰符修饰的成员变量和成员方法可以被所有的类访问
final修饰符 (final的中文意思 :最终的)
被final修饰的变量最多只能被赋值一次
被final修饰的变量一经赋值,则不能再被改变
final int a = 10 ;
a = 20 ; //这是错误的
被final修饰的成员变量,成员必须赋初始值,一经赋值则不能被改变
被final修饰的局部变量,可以先声明,等到使用的时候再赋值,但是只能被赋值一次
面向对象的三大特点
封装,继承,多态
封装:
这里讲的封装,主要是对属性和方法的封装,
对属性的封装:
需要把属性私有化,然后对外提供公共的访问方法
对方法的封装:
将外部可以访问的方法使用public修饰,将外部不能访问的方法使用private修饰
继承:
将多个具有相同属性和行为的类的相同的属性和行为抽取出来,封装到一个单独的类中,
这时,具有相同属性和行为的类就不必要重复的编写这些行为和属性,只需要继承封装后的那一个新类就能拥有这些属性和行为
这些具有相同属性和行为的类叫做子类,封装的新类叫做父类或者超类
如:狗 , 猫 , 猪 都有共同的属性 性别,年龄 ,都有共同行为 吃 ,睡
就将这些相同的属性和行为抽取出来,封装一个新类 动物
动物 有性别 ,年龄 等属性 有 吃,睡等行为
此时:狗只需要继承动物 就可以拥有动物的属性和行为
语法
[修饰符] class 狗 extends 动物
{ }
注意:子类不能继承父类私有的属性和方法
子类除了能够拥有父类非私有的属性和方法外,还有可以扩展自己特有的属性和方法
包的创建和使用
包:是Java语言中用来管理类,接口等源文件的一个管理工具,类似于windows系统中的文件夹
包的声明:
package 包名 ;
声明包时需要注意的点:
1,采用多级包名
2,一般使用小写字母
3,包名不能以java或javax开头
4,一般情况主包名采用的是倒置的域名.工程名.功能名
5,包的声明语句必须位于源文件的第一行
包的导入:
需要使用关键字 import
import 包名.类名|接口名 ; //导入指定包中指定的类或者接口
import 包名.* ; //导入指定包中所有的类和接口
什么时候需要导入包?
当一个包里面的类,需要引用另一个包里面的类时,则需要导入包
访问修饰符 (public private (default) protected)
private 私有的,由private修饰的变量和方法只能在本类中被访问
default 默认的(当变量及方法没有访问权限修饰符时则默认为default), 由default修饰的变量和方法可以在本类访问以及与其在同一个包中的其他类访问
protected 受保护的 在default的基础上,增加了其他包中的继承了该类的子类
public 公共的 可以被其他所有的类方问
final修饰符(中文含义:最终的)
被final修饰的变量最多只能被赋值一次,一经赋值就不能改变
封装
对方法和属性的封装
对属性的封装:
将属性私有化,然后对外提供公共访问接口 提供 get set方法
对方法的封装:
将你不愿意提供给外界访问的方法私有化(用private修饰),希望外界访问的方法共有化(用public修饰)
继承
父类是子类的抽象
把具有相同属性和行为的多个类的相同的属性和行为抽取出来,封装成一个新的类,
这个新的类叫做父类,这具有相同属性和行为的多个类叫做子类,需要继承父类。
继承的语法
[修饰符] class 子类名 extends 父类名
{
}
子类可以有自己扩展的属性和方法
继承的特点:
1,Java语言当中,如果一个类没有明确的指出它父类,那么默认继承的Object类
2,Java语言当中,类的继承只支持单继承,即一个类只能有一个直接父类 extends 后只跟一个父类名
3,Java语言当中,支持多层继承
4,Java语言当中,子类只能继承父类非私有的属性和方法,不能继承父类的构造器
注意:
1,不要为了获得某个类中的功能,而去继承这个类
2,继承关系中,类与类之间一定要有所属关系,如:狗是动物的一种,动物是生物的一种
包对于继承的影响(关系到访问权限修饰符)
private 修饰的属性和方法是私有的,只能在本类访问,不能继承
default 修饰的属性和方法,可以被本类访问,可以被同包内中的其他类所访问 能同包内中的子类所继承
protected 修饰的属性和方法,在default的基础上,增加了可以被其他包中的子类继承
public 修饰的属性和方法,可以被任意类访问
子类对象的创建流程
当新创建一个子类对象时,实际上是先调用了父类的无参构造器,然后才调用了子类自身的构造器
每一个子类构造器中默认的第一行有隐式调用父类的无参构造器
如果父类只提供了有参的构造器,那么子类需要在每一个构造器的第一行显示的调用父类的有参构造器
super关键字
每一个类中都有两个特殊的成员变量,一个是this 代表当前对象,一个是super,代表的父类对象
this有两个作用:
当成员变量和局部变量发生冲突的时候,可以使用this.变量名来标注成员变量
当一个构造器中需要调用本类的另一个构造器时,可以使用this([参数]);来进行调用,但是this()必须写在构造器的方法体的第一行
super的作用:
1,当子类中的变量和父类中的成员变量重名时,可以使用super.变量名来标注 父类的成员变量
2,当子类的构造器调用父类的构造器时,使用super([参数]); 注意:super()必须写在子类构造器方法体中的第一行
所以不能同时显式的存在super(),this()。
3,当在子类的方法,需要调用父类的方法时,super.父类方法名([参数]);
方法的重写 override
当子类从父类继承过来的方法,无法满足子类的功能需求时,子类需要对该方法进行重新实现,这个个过程叫做方法的重写,也叫做方法的覆盖,或者复写
方法重写的条件:
1,一个类需要重写另一个类中的方法,那么它们一定要有继承关系
2,子类中重写的方法的访问权限修饰符的权限一定要大于等于父类方法的访问权限
3,子类重写的方法的方法名,参数列表,返回值的数据类型必须和父类保持一致
多态:就是指的是一个事物多种形态
方法的多态
方法的重载(发生在本类中)
方法的重写(发生在继承中)
变量的多态(这里主要指对象的多态)
1,向上转型
父类变量 Father f ; 既可以保存父类对象的引用,也可以保存子类对象引用
Father (父类) Son(子类)
Father f ;
Son s = new Son();
f = s ;
注意:当对象发生向上转型时,只会保留父类中可以被继承的方法和变量,子类重写的方法会保留
2,向下转型
子类变量可以存储子类对象的引用,也可以存储父类对象的引用
注意:如果需要进行向下转型,则应该先进行向上转型
抽象方法:
当父类中的方法不确定子类应该实现什么样的功能时,可以把这个方法声明为抽象方法
抽象方法的声明语法:
[修饰符(public)] abstract void|返回值数据类型 方法名([参数类型 参数名]);
注意:抽象方法必须存在于抽象类中,抽象方法没有方法体
抽象类的声明语法:
[修饰符(public)] abstract class 类名
{
成员变量
成员方法(可以是抽象的,也可以不是抽象的)
代码块
}
抽象类使用注意点:
1,抽象类不能被实例化(不能创建对象, 不能 new)
2,抽象类就是用来被继承的
3,抽象类中可以没有抽象方法,但是抽象方法一定要存在于抽象类中
4,抽象类中可以存在具象方法(有方法体的方法)
5,抽象类的子类必须实现(重写)抽象类中的所有的抽象方法,否则子类就需要声明为抽象类
6,抽象方法被重写的时候,需要去掉关键字abstract,并为方法加上方法体