java是纯粹的面向对象的语言
也就是万事万物皆是对象
程序是对象的集合,他们通过发送消息来相互通信
每个对象都有自己的由其他的对象所构建的存储,也就是对象可以包含对象
每个对象都有它的类型 也就是类
某一特定类型的所有对象都可以接收相同的消息,因为同一类事物有共同的特性
面向对象开发
•就是不断的创建对象,使用对象,指挥对象做事情。
面向对象设计
•其实就是在管理和维护对象之间的关系。
面向对象特征
•封装(encapsulation)
•继承(inheritance)
•多态(polymorphism)
现实应用场景终归是要解决问题,面向过程的语言,是一个方法伴随着另一个方法的调用
随着应用规模的不断变大,显然软件代码管理变得更加困难
面向对象把功能逻辑封装到类本身,用对象去调用功能 持有数据,结构更加自然,也更符合人们的思维习惯
也就是说java中类 和对象 是划分逻辑功能的具体单位
面向对象的语言中,都会有类这个概念,一类事物他们有共同的属性和行为
java中描述事物通过类的形式体现,类是具体事物的抽象,概念上的定义。
对象即是该类事物实实在在存在的个体。
类:是一组相关的属性和行为的集合
对象:是该类事物的具体体现
成员变量与局部变量
在类中的位置不同
•成员变量 类中方法外
•局部变量 方法内或者方法声明上
在内存中的位置不同
•成员变量 堆内存
•局部变量 栈内存
生命周期不同
•成员变量 随着对象的存在而存在,随着对象的消失而消失
•局部变量 随着方法的调用而存在,随着方法的调用完毕而消失
初始化值不同
•成员变量 有默认的初始化值
•局部变量 没有默认的初始化值,必须先定义,赋值,才能使用。
this:代表所在类的对象引用
记住:
•方法被哪个对象调用,this就代表那个对象
什么时候使用this呢?
•局部变量隐藏成员变量
static关键字
可以修饰成员变量和成员方法
static关键字特点
•随着类的加载而加载
•优先于对象存在
•被类的所有对象共享
•这也是我们判断是否使用静态关键字的条件
•可以通过类名调用
static关键字注意事项
•在静态方法中是没有this关键字的
•静态方法只能访问静态的成员变量和静态的成员方法
静态变量与成员变量
所属不同
•静态变量属于类,所以也称为为类变量
•成员变量属于对象,所以也称为实例变量(对象变量)
内存中位置不同
•静态变量存储于方法区的静态区
•成员变量存储于堆内存
内存出现时间不同
•静态变量随着类的加载而加载,随着类的消失而消失
•成员变量随着对象的创建而存在,随着对象的消失而消失
调用不同
•静态变量可以通过类名调用,也可以通过对象调用
•成员变量只能通过对象名调用
匿名对象
匿名对象:就是没有名字的对象。
•是对象的一种简化表示形式
匿名对象的两种使用情况
•对象调用方法仅仅一次的时候
•作为实际参数传递
值传递
java中全部都是值传递 引用类型传递的也是值 只不过是地址
初始化过程
Student s = new Student();在内存中做了哪些事情?
•加载Student.class文件进内存
•在栈内存为s开辟空间
•在堆内存为学生对象开辟空间
•对学生对象的成员变量进行默认初始化
•对学生对象的成员变量进行显示初始化
•通过构造方法对学生对象的成员变量赋值
•学生对象初始化完毕,把对象地址赋值给s变量
封装
封装概述
•是指隐藏对象的属性和实现细节,仅对外提供公共访问方式。
好处:
•隐藏实现细节,提供公共的访问方式
•提高了代码的复用性
•提高安全性。
封装原则:
•将不需要对外提供的内容都隐藏起来。
•把属性隐藏,提供公共方法对其访问。
构造方法
特点:
1.函数名与类名相同
2.不用定义返回值类型
3.没有具体的返回值。
作用:
给对象进行初始化。
注意:
1.默认构造函数的特点,如果自建将会失去默认,需要的话必须显式
2.多个构造函数是以重载的形式存在的。
代码块
•在Java中,使用{}括起来的代码被称为代码块,根据其位置和声明的不同,可以分为局部代码块,构造代码块,静态代码块,同步代码块(多线程讲解)。
•局部代码块
•在方法中出现;限定变量生命周期,及早释放,提高内存利用率
•构造代码块
•在类中方法外出现;多个构造方法方法中相同的代码存放到一起,每次调用构造都执行,并且在构造方法前执行
•静态代码块 在类中方法外出现,加了static修饰
•在类中方法外出现,并加上static修饰;用于给类进行初始化,在加载的时候就执行,并且值执行一次。
执行顺序 静态代码块 > 构造代码块 > 构造方法
private关键字
(1)私有的意义,可以修饰成员变量和成员方法
(2)特点:
被private修饰的后的成员只能在本类中被访问
(3)private的应用:
以后再写一个类的时候:
把所有的成员变量给private了
提供对应的getXxx()/setXxx()方法
继承
多个类中存在相同属性和行为时,
将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那个类即可。
多个类可以称为子类,单独这个类称为父类或者超类。
子类可以直接访问父类中的非私有的属性和行为。
通过extends 关键字让类与类之间产生继承关系。
•class SubDemo extendsDemo{}
继承的出现提高了代码的复用性。
继承的出现让类与类之间产生了关系,提供了多态的前提。
Java只支持单继承,不支持多继承。
•一个类只能有一个父类,不可以有多个父类。
•class SubDemo extends Demo{} //ok
•class SubDemo extends Demo1,Demo2...//error
Java支持多层继承(继承体系)
•class A{}
•class B extends A{}
•class C extends B{}
定义继承需要注意:
•不要仅为了获取其他类中某个功能而去继承
继承缺点:
1,让类的耦合性增强。这样某个类的改变,就会影响其他和该类相关的类。
原则:低耦合,高内聚。
耦合:类与类的关系
内聚:自己完成某件事情的能力
2.打破了封装性
super
this代表本类对象的引用
•类与类之间要有所属( " is a " )关系,xx1是xx2的一种。
super代表父类的内存空间的标识。
当子父类出现同名成员时,可以用super进行区分
子类要调用父类构造函数时,可以使用super语句。
方法覆盖 override
子类中出现与父类一模一样的方法时,会出现覆盖操作,也称为重写或者复写。
父类中的私有方法不可以被覆盖。
在子类覆盖方法中,继续使用被覆盖的方法可以通过super.函数名获取。
覆盖注意事项:
•覆盖时,子类方法权限一定要大于等于父类方法权限
•静态只能覆盖静态。
覆盖的应用:
•当子类需要父类的功能,而功能主体子类有自己特有内容时,可以复写父类中的方法,
这样,即沿袭了父类的功能,又定义了子类特有的内容。
子类实例化过程
子类中所有的构造函数默认都会访问父类中空参数的构造函数
因为每一个构造函数的第一行都有一条默认的语句super();
子类会具备父类中的数据,所以要先明确父类是如何对这些数据初始化的。
当父类中没有空参数的构造函数时,子类的构造函数必须通过this或者super语句指定要访问的构造函数。
final关键字
final可以修饰类,方法,变量。
final修饰的类不可以被继承。
final修饰的方法不可以被覆盖。
final修饰的变量是一个常量。只能被赋值一次。
内部类只能访问被final修饰的局部变量。
1,变量
a:基本类型 值不能发生改变
b:引用类型 地址值不能发生改变,但是对象的内容是可以改变的
2,初始化时机
a:只能初始化一次。
b:常见的给值方式
定义的时候。(推荐)
构造方法中。
抽象类
抽象定义:
•抽象就是从多个事物中将共性的,本质的内容抽取出来。
抽象类:
•Java中可以定义没有方法体的方法,该方法的具体实现由子类完成,该方法称为抽象方法,
包含抽象方法的类就是抽象类。
抽象方法的由来:
•多个对象都具备相同的功能,但是功能具体内容有所不同
那么在抽取过程中,只抽取了功能定义,并未抽取功能主体,那么只有功能声明,没有功能主体的方法称为抽象方法。
抽象类和抽象方法必须用abstract关键字来修饰。
抽象方法只有方法声明,没有方法体,定义在抽象类中。
•格式:修饰符 abstract 返回值类型 函数名(参数列表) ;
抽象类不可以被实例化,也就是不可以用new创建对象。原因如下:
•抽象类是具体事物抽取出来的,本身是不具体的,没有对应的实例。
•而且抽象类即使创建了对象,调用抽象方法也没有意义。
抽象类通过其子类实例化,而子类需要覆盖掉抽象类中所有的抽象方法后才可以创建对象,否则该子类也是抽象类。
接口
格式:
interface {}
接口中的成员修饰符是固定的。
•成员常量:public static final
•成员函数:public abstract
•接口中的成员都是public的。
没有构造方法
接口的出现将“多继承”通过另一种形式体现出来,即“多实现”。
接口是对外暴露的规则。
接口是程序的功能扩展。
接口的出现降低耦合性。
接口可以用来多实现。
类与接口之间是实现关系,而且类可以继承一个类的同时实现多个接口。
接口与接口之间可以有继承关系。
•类实现接口用implements表示
•格式:
class 类名 implements 接口名 {}
•接口不能实例化 那么,接口如何实例化呢?
按照多态的方式,由具体的子类实例化。其实这也是多态的一种,接口多态。
•接口的子类 要么是抽象类 要么重写接口中的所有抽象方法
类与类,类与接口以及接口与接口的关系
类与类
•继承关系,只能单继承,但是可以多层继承
类与接口
•实现关系,可以单实现,也可以多实现。还可以在继承一个类的同时实现多个接口
接口与接口
•继承关系,可以单继承,也可以多继承
多态
某一类事物的多种存在形态
程序中体现:
父类或者接口的引用指向或者接收自己的子类对象。
好处和作用:
多态的存在提高了程序的扩展性和后期可维护性
前提:
•需要存在继承或者实现关系
•要有覆盖操作
•有父类或者父接口引用指向子类对象。
包
对类文件进行分类管理。
给类提供多层命名空间。
写在程序文件的第一行。
类名的全称的是 包名.类名。
包也是一种封装形式。
定义包的格式
•package 包名;
•多级包用.分开即可
注意事项:
•package语句必须是程序的第一条可执行的代码
•package语句在一个java文件中只能有一个
•如果没有package,默认表示无包名
类:
•默认default,public,final,abstract
•我们自己定义:public居多
成员变量:
•四种权限修饰符均可,final,static
•我们自己定义:private居多
构造方法:
•四种权限修饰符均可,其他不可
•我们自己定义:public 居多
成员方法:
•四种权限修饰符均可,fianl,static,abstract
•我们自己定义:public居多
import
简化类名。
一个程序文件中只有一个package,可以有多个import。
用来导包中的类,不导入包中的包。
内部类
将一个类定义在另一个类的里面,对里面那个类就称为内部类(内置类,嵌套类)。
访问特点:
•内部类可以直接访问外部类中的成员,包括私有成员。
•而外部类要访问内部类中的成员必须要建立内部类的对象。
成员内部类 局部内部类
内部类定义在成员位置上
•可以被private static成员修饰符修饰。
•被static修饰的内部类只能访问外部类中的静态成员。
成员内部类不是静态的:
外部类名.内部类名 对象名 = 外部类名.new 内部类名();
成员内部类是静态的:
外部类名.内部类名 对象名 = new 外部类名.内部类名();
内部类定义在局部位置上
•也可以直接访问外部类中的成员。
•同时可以访问所在局部中的局部变量,但必须是被final修饰的。
内部类访问外部类属性 外部类名称.this.属性名
匿名内部类
就是内部类的简化写法。
前提:
•内部类可以继承或实现一个外部类或者接口。
格式为:
•new外部类名或者接口名(){ 覆盖类或者接口中的代码,(也可以自定义内容。) }
简单理解:
•就是建立一个带内容的外部的类或者接口的子类匿名对象。
Object类
(1)Object是类层次结构的根类,所有的类都直接或者间接的继承自Object类。
(2)Object类的构造方法有一个,并且是无参构造
这其实就是理解当时我们说过,子类构造方法默认访问父类的构造是无参构造
(3)要掌握的方法:
toString()
返回对象的字符串表示,默认是由类的全路径+'@'+哈希值的十六进制表示。
这个表示其实是没有实际意义的,一般子类都会重写该方法。
equals()
比较两个对象是否相同。默认情况下,比较的是地址值是否相同。
而比较地址值是没有意义的,所以,一般子类也会重写该方法。
(4)要了解的方法:
hashCode() 返回对象的哈希值。不是实际地址值,可以理解为地址值。
getClass() 返回对象的字节码文件对象
finalize() 用于垃圾回收,在不确定的时间
clone() 可以实现对象的克隆,包括成员变量的数据复制,但是它和两个引用指向同一个对象是有区别的。
(5)两个注意问题;
直接输出一个对象名称,其实默认调用了该对象的toString()方法。
==和equals()的区别?
==
基本类型:比较的是值是否相同
引用类型:比较的是地址值是否相同
equals()
只能比较引用类型。默认情况下,比较的是地址值是否相同。
但是,我们可以根据自己的需要重写该方法。