面向对象
1、java 是一种面向对象的语言
2、主要描述一件事情或者程序执行的过程中的每一个步骤
封装
对程序进行归纳、封装
类
1、具有相同的属性或者特性的一类事物
2、类也是一种引用数据类型
对象
语法:类名 对象名 = new 类();
- 匿名对象
语法:new 类名();
1、它是一个临时的对象,只能引用一次
构造函数
1、用来创建对象的
2、构造函数的特点:
<1>如果没有有参构造函数,系统会自动生成一个无参构造函数让用户进行调用(这个无参构造函数是隐式,是直接跳转到类名的)
<2>构造函数的名字和类名是完全相同的,包括大小写
<3>构造函数没有void,也没有返回值的数据类型
<4>如果有了一个有参构造函数,还想要调用无参构造函数的时候,系统就不会自动生成(必须手动写一个无参构造函数之后才能调用)
<5>如果没有显示的写构造函数,那么可以直接调用无参构造函数,如果写了有参构造函数,没有写无参构造函数,调用无参构造函数会报错
- 无参构造函数
语法:访问控制修饰符 类名(){}
- 有参构造函数
语法:访问控制修饰符 类名(参数列表){
this . 属性 = 参数;
}
- get set 方法
• set 方法
语法:public void set属性(参数数据类型 参数){
this.属性 = 参数;
}
1、set方法:赋值
2、set属性:是方法的名称,属性的首字母要大写
3、set方法是一个有参数无返回值的方法
• get 方法
语法:public 属性的数据类型 get属性(){
return 属性;
}
1、get方法:取值
2、get方法就是一个有返回值无参数的方法
- toString 方法
1、toString():方法,这个方法来源于Object类,所有的类都可以重写这个方法
2、作用是用来将对象的信息进行集体输出,输出的信息可以根据情况决定
内部类
将一个类写在其他的类的内部,可以写在其他类的成员变量位置或者局部变量位置,这是写在其他类内部的类就叫内部类。其他的类称为外部类。
关于内部类的注意事项:
1、内部类可以使用外部类的成员变量和方法,但是static修饰的,需要创建对象
2、局部内部类如果需要使用外部方法的局部变量,该局部变量必须使用final进行修饰
3、局部内部类的使用范围仅限于声明的区域
4、静态内部类中不能直接使用外部类的实例方法或实例变量,创建外部对象,才能通过对象进行调用
- 成员内部类(静态内部类和非静态内部类)
成员内部类,定义在外部类的成员的位置。与类中的成员变量相似,可以通过外部类对象进行访问
创建成员内部类对象
外部类名.内部类名 变量名 = new 外部类名().内部类名();
- 局部内部类
定义在外部类方法中局部变量的位置。与访问方法中的局部变量相似,可以通过调用方法进行访问
- 匿名内部类
匿名内部类的概念(局部内部类)说明定义在方法里面
最常用到的内部类就是匿名内部类,它是局部内部类的一种。
定义匿名内部类的两个含义:
1、临时定义某一个指定类型的子类
2、定义后即刻创建刚刚定义好的这个子类的对象
匿名内部类的作用和格式
作用:匿名内部类是创建某个类型的子类对象的快捷方式
格式:
new 父类或接口(){
//进行方法重写
}
- 静态内部类
是指在创建内部类的时候使用static修饰的内部类
1)在创建静态内部类的时候,不需要创建外部类的对象
外部类名.内部类名 对象名 = new 外部类名.内部类名();
2) 静态内部类中可以定义静态成员和非静态成员。其他类在调用外部类中的静态内部类的时候,需要通过完整的类名访问静态内部类中的静态的成员.如果要访问静态内部类中的其他非静态成员,需要通过静态内部类的对象进行调用
int a = 10;//静态内部类的非静态成员变量
System.out.println(oi.a);//访问静态内部类中非静态的变量
static int b = 20;//静态内部类的静态的成员变量
System.out.println(Outer_02.Inner_02.b);//访问静态内部类中静态的变量
3) 静态内部类可以直接访问外部类中的静态变量,如果要访问外部类中的非静态的变量,则需要通过外部类的实例去访问
nt a = 10;//外部非静态成员变量
int a2 = o.a;//如果要访问实例变量,就要通过对象访问
static int b = 20;//外部静态成员变量
int b2 = b;//访问静态变量直接访问
属性
语法:访问控制修饰符 数据类型 属性名;
1、在描述整个对象的时候,从对象的特点中提取出来的特点
访问控制修饰符
1、在java编程的过程中
属性没有特殊要求的情况下使用private进行修饰
方法没有特殊要求的情况下使用public进行修饰
- private(私有的)
1、使用private修饰的元素,只能在同一个类中访问
2、一般应用于属性
- public(公有的)
1、使用public修饰的元素,可以在整个项目中访问
2、一般应用于方法
- default/package(默认不写的)
1、使用default修饰的元素可以在同一个类和同一个包中访问
- protected(受保护的)
1、使用protected修饰的元素可以在同一个类,同一个包,不同包的子类中访
方法
语法:访问控制修饰符 返回值的数据类型/void 方法名(数据类型 参数名1 , 数据类型 参数名2 ...){
方法体;
return 值;
}
1、这一类事物可以做的事情,或者说是具有的行为
2、注意事项:
<1>返回值的数据类型和void只能有一个
<2>返回值的数据类型控制的是return后面的值的类型
<3>参数列表中可以没有值,也可以有多个值
<4>方法中如果有参数传入,一般都是对参数进行处理,参数是执行过程中的辅助值或者关键值,这些值是可以改变的(未知的),
<5>方法没有调用的时候不会执行,调用了之后才会执行
<6>如果方法没有返回值,我们可以省略return不写,但是如果有return放在那里也没有错,但是不能有值
<7>返回值可以看做是方法最终执行的结果
<8>如果调用方法的时候,方法没有参数,那么括号里面就不需要添加任何的值
<9>如果方法最终是以返回值的形式来得到值的,那么将方法的调用可以进行赋值或者输出,如果方法最终的形式是输出语句,那么我们就不能将方法的调用放在输出语句里面了
返回值的数据类型
1、可以是基本数据类型也可以是引用数据类型
void
1、无返回值的
方法体
1、可以是任何的内容,不如:输出,输入,随机数,判断,循环...
return
1、返回的关键字
继承
1、类和类之间的关系
横向关系:
1、依赖关系:某一对象在执行指定方法时,需要其他的对象参与完成:人喝水需要使用杯子
2、关联关系 1 - 1 1 - n n - n
它体现的是两个类,或者类与接口之间的一种语义级别的强依赖关系。
这种关系比依赖关系更强,关系不是临时性的是长期的
表现在代码层面两个相关联的类之间,A类作为B类的关联类或者属性类,A类可以调用
B类找那个的所有的属性和方法
3、组合关系 包含关系 可以分离的 计算机 - cpu 多个员工 ---> 公司
产生一个订单:商品信息 客户信息 订单信息
4、聚合关系 强包含关系 不可分离的 人 - 大脑
纵向关系:
1、继承关系 (父类和子类之间的关系)
子类继承父类
2、实现关系(接口和实现类)
实现类实现接口
接口:身份
继承的好处:
1、继承的出现提高了代码的可复用性,提高了软件的开发效率
2、继承的出现让类与类之间存在了纵向的关系,为后面多态提供了前提
父子类
继承的特点:
1、子类继承于父类,可以获取到父类中所有非私有的属性和方法
2、如果子类有自己独有的方法,那么可以直接创建子类对象来进行调用
3、一个子类只能有一个父类,但是如果A类是B类的父类,A类又是C类的子类,那么相当于C类是B类的祖父类
java中不能对继承,但是可以多层继承,子类也可以那到祖父类中的非私有的属性和方法
4、子类不能继承父类的构造函数,虽然构造函数也是public修饰的,但是构造函数是用来创建对象的,所以
子类不能继承父类的构造函数来创建父类对象
5、一个父类可以有多个子类
如果要调用父类中的元素,使用super关键字,比如在子类调用父类构造函数中的元素的时候
重写&重载
方法的重写:(三同一不同)
当两个方法名字相同的时候就直接默认是方法重新
环境:两个类存在继承关系的时候,发生在继承父类的子类中
要求:
1、方法名必须相同,包括大小写
2、方法的返回值类型必须相同
3、方法的参数列表必须相同
4、方法体不同
方法重载:
* 发生在同一个类中
* 要求:方法名相同,参数列表不同
* 参数列表不同:
* 参数的个数不同
* 参数的数据类型不同
* 参数的顺序不同
接口
1、什么叫接口
interface:接口;
接口的概念:
接口是功能的集合,同样也可以看做是一种引用数据类型,是比抽象还抽象的“类”
接口只描述程序执行所应该具备的方法,没有方法的具体实现,具体的实现由实现这个接口的实现类来处理(相当于接口的子类)
这样做的意义是将功能的定义和功能的实现区分开
关键:一切事物均有功能,一切事物都有接口
接口不创建对象!!!
接口中可以定义方法,但是方法也有固定的修饰符,public abstract
在jdk1.8以后可以定义static和default修饰的方法
类和接口之间实现关系,implements 一个类可以实现多个接口
类和类之间是继承关系,extends 一个类只能有一个父类
接口和接口之间之间多继承,extends 一个子接口可以继承多个父接口
实现类在实现接口的情况下还可以继承父类
接口在开发中的好处:
1、接口的出现扩展了项目的功能
2、接口其实就是显现出来的规则
3、接口的出现降低了类和类之间的耦合性,即设备和设备直接实现了解耦
接口的出现方法后期的使用和维护,一方是使用接口,一方是实现接口
实现类
必须实现接口中所有的方法,才能创建对象,否则报错
如果方法不想实现,可以使用abstract修饰一下
抽象类
语法:public abstract class 类名{//抽象类
public abstract 数据类型 方法名();//抽象方法
}
抽象类是java中的重要特点之一,可以将一个类或者一个方法使用abstract关键字修饰,使用abstract修饰的类无法被实例化,使用abstract修饰的方法不能有具体的实现,必须由子类来实现
1、抽象方法和抽象类都是使用abstract修饰的,抽象方法必须放在抽象类中、
2、在抽象类中可以写普通的方法,并且方法必须实现
子类
子类继承抽象类之后,要实现抽象类中的所有的抽象方法,如果抽象类中有具体方法的实现(一般不这么写),子类也可 以调用
final(最终的)
可以用来修饰:属性,方法,类
修饰类:类不能被继承
修饰方法:不能被重写
修饰属性:不能被赋值
static(静态的)
1、static不能修饰类,可以修饰属性
2、不能修饰构造方法,可以修饰普通方法
3、被static修饰的游离块叫静态块
<1>被static修饰的成员变量,属于类本身.不属于这个类的某一个对象(也就是说,多个对象在访问或者修改static修饰的成员变量的时候,其中一个对象对变量进行改变,其余的对象调用的都是改变之后的)
<2>用static修饰的属性或者方法,建议直接使用类名进行调用
访问静态成员的时候的格式:
类名.静态成员变量名;
类名.静态成员方法名(参数);
对象名.静态成员变量名; --- 可以但不建议使用,因为会出现警告
对象名.静态成员方法名(参数); --- 可以但不建议使用,因为会出现警告
static的注意事项
1、静态内容是优先于对象存在,在静态方法中只能直接访问静态的成分
2、在同一个类中,静态成员只能直接访问静态成员,如果想要访问非静态成员,必须创建对象之后在调用
3、在所有的函数中有一个特殊的方法,main这个方法仅仅是程序的入口,它不属于任何的一个对象,可以定义在任何的类中
static总结:
static:关键字,静态的意思
可以用来修饰类中的成员(成员变量,成员方法,匿名块,内部类)
注意:也可以用来修饰成员内部类
特点:
被静态修饰的成员,会被所有的对象共享
被静态修饰的成员,可以通过类名直接调用
注意事项:
静态的成员,随着类的加载而加载,优先于对象存在
在静态方法中,没有this super关键字
在静态方法中,只能调用静态的成员(静态的成员变量,静态方法)
静态游离块:类加载的时候最先执行,并且只执行一次
游离块(初始化块)
语法: {//方法执行的内容}
在java中如果存在多个构造器,每个构造器中都有重复的代码时,可以将重复的初始化代码归纳到一个游离块中,进行统一执行,从而解决构造器中代码重复的问题.游离块一般在构造器执行之前先执行,在构造对象的时候隐式
调用(自动调用),本质上是一个方法体的执行体
游离块的特点:
1、游离块在普通方法执行之前先执行,无论游离块在什么位置
2、创建几个对象,游离块就执行多少次
3、游离块在创建对象的时候就一定会执行,并且在其他方法执行之前先执行
4、一个对象只执行一次游离块
5、游离块在构造函数执行之前先执行,所以游离块在对象创建之前就存在了
6、当两个类之间存在继承关系的时候,先执行父类中的游离块,然后执行父类的构造函数,执行完成之后执行子类的游离块,然后执行子类的构造函数,最后执行调用的方法
7、如果游离块加了static,那么同一个类中创建了多个对象,静态游离块只执行一次
成员变量和局部变量之间的区别
成员变量:属性,实例变量,全局变量,定义在类体中,方法外面的变量
局部变量:属于方法的变量,只在方法内或方法声明上(形参);
1、修饰符的问题
成员变量的修饰符:private protected public static final
局部变量:final
2、内存中的存放位置
成员变量:在堆中存放,属于对象
局部变量:在栈中存放,属于方法
3、初始值
成员变量:有默认的初始值(0,false,0.0,null,\u0000)
局部变量:没有初始值,必须先定义,赋值,才能使用
4、生命周期
成员变量:和对象的生命周期一致
局部变量:和方法的生命周期一直,一个对象对方法调用完毕之后,局部变量就会销毁
堆和栈的区别
在java中,内存分为两种,一种是栈内存,另一种是堆内存
1、堆内存
(1)什么是堆内存:
堆内存是java内存中的一种,它的作用是用于存储java中的对象和数组,当我们new一个对象的时候,或者创建一个数组的时候,就会在堆内存中开辟一个空间,用于存储元素。
(2)堆内存的特点:
第一点:堆其实可以看成一个管道,或者平时排队买票的情况,先进先出,后进后出 也就相当于,先排队的先买票,后排队的后买
第二点:对内存可以看做动态的分配内存的大小,信息的生存周期也不需要提前告诉编辑器,因为在运行的时候会动态的分配内存,缺点就是动态分配内存导致,导致存取的速度比较慢
(3)new对象在堆内存中如何分配
由java虚拟机的自动垃圾回收器来进行管理
2、栈内存
(1)什么是栈内存
栈内存是java中的另外一个内存,主要用来执行程序使用,比如:将基本数据类型的对象和变量进行引用的时候使用
(2)栈内存的特点:
1、栈内存像一个瓶子,先放进去的东西,会到达内存的底部,然后取出来的时候,后放进去的先取出来
先进后出,后进先出
2、存取速度比堆内存要快,速度仅次于寄存区,栈内的数据可以实现共享,但是缺点存在栈内存中的数据大小与生存期必须确定,缺乏灵活性
(3)栈内存的分配机制
栈内存称为一级缓存,有垃圾回收机制自动回收
堆和栈的区别:
java虚拟机为每个新创建的对象(线程)分配了内存空间。也就是说,对于一个java程序来说,程序的运行是通过对内存的调用和,信息的存储来完成。
1、差异
(1)堆内存用来存储new创建的对象和数组
(2)栈内存一般用来存储方法或者局部变量
(3)堆内存是先进先出,后进后出
(4)栈内存是后进先出,先进后出
2、相同
(1)都是java内存的一种
(2)内存的回收都是由java虚拟机来进行回收处理的,程序员不进行这方面的处理
静态常量
定义静态常量
在开发的过程中,我们想要在类中定义一个静态常量,通常使用 public static final修饰的变量来完成定义.
此时变量名全部大写,多个单词使用_进行连接。
public static final 数据类型 常量名 = 值;
public static final int AGE = 18;
接口和抽象类的区别
相同点:
1、都是位于继承的顶端,用于被其他类实现或者继承
2、都不能直接实例化对象
3、都包含了抽象方法,子类都必须实现这些抽象方法
区别:
抽象类 接口
关键字 abstract class interface
内部成员 什么都可以定义(不能定义default修饰的方法) 静态常量 抽象方法 default方法 static方法
抽象方法 必须使用abstract进行修饰 可以省略abstract
类和他们的关系 类 extends 抽象类(单继承) 类 extends 父类 implements 接口1,接口2(多实现)
二者之间如何选用:
优先使用接口,尽量少使用抽象类
最为理想的系统设计规范应该是所有的定义和实现要进行分离
接口比抽象类还抽象,符合系统的设计规范
多态
在面向对象的语言中,接口的多种不同的实现方式成为多态。
java作为面向对象的语言,同样可以描述一个事物的多种形态。比如Student类继承了Person类,一个Student的对象既可以表现为学生,也可以表现为Person
在java中多态的代码体现为,一个子类对象既可以给这个子类作为引用变量进行赋值,也可以给这个子类的父类(接口)进行赋值。
重点:
1、最终多态体现为父类引用变量,指向子类对象
2、多态的前提是:两个类之间必须有继承关系,接口与类之间必须有实现关系。否则无法实现多态
3、在使用多态后,父类引用变量调用方法的时候,会调用子类重写之后的方法
简单地说:建立一个父类对象的引用,它所指向的对象可以是父类的对象,也可以是子类的对象。
在java当子类拥有和父类相同的函数的时候,当通过父类对象的引用调用这个函数的时候,调用的是子类中的函数
Fu f = new F();//创建父类本身的对象
F f = new Z();//可以是子类的对象
多态的好处和弊端
当父类的引用指向子类对象的时候 F f = new s(); 就发生了向上转型,即把子类型对象转成父类型对象。
向上转型的好处是隐藏了子类类型,只能使用父类共性的内容,而无法子类特有的方法,功能有限制。
向下转型的好处:可以使用子类特有的功能
弊端:需要面对具体的子类对象,在向下转型时容易发生类型转换异常.所以在转型之前必须先做判断
多态的优势:
1、降低了类之间的耦合度
2、面向抽象编程
3、提高了程序的可扩展性
多态的成员特点
<1>多态中的成员变量
当子父类中出现同名的成员变量时,多态调用变量的时候:
简单记:编译和运行都看等号左边的
<2>多态成员方法
编译时期:参考引用变量所属的类,如果没有类中要调用的方法,就会编译失败
运行时期:参考引用变量所指向的对象所有的类,并运行对象所属的类中的成员方法
简单记:编译的时候看左边,执行的时候看右边
instanceof 关键字
instanceof 关键字用来判断某一个对象是否属于某一种数据类型
最终的结果的数据类型是布尔类型的值
多态的转型
向上转型
向上转型:当有子类的对象赋值给父类的引用时,便是向上转型,多态本身就是向上转型的过程。
使用格式:
父类类型 变量名 = new 子类类型();
向下转型
向下转型:一个已经向上转型的子类对象,可以使用强制类型转换的格式,将父类的引用指向子类对象,这个过程就叫向下转型,如果是直接创建父类对象,是无法向下转型的
注意:
向下转型之前,必须先向上转型
或者向下转型之前,使用 instanceof 判断当前对象的格式
使用格式:
子类类型 变量名 = (子类类型)父类类型的变量;
Student stu = (Student)p;//变量p实际上指向student对象