#1、面向对象概述
面向过程:强调的是行为面向对象:强调的是对象(将行为封装到对象里面)
核心思想:万事万物皆对象
案例:把大象装进冰箱
面向过程
1、打开冰箱门
2、把大象装进去
3、关上冰箱门
面向对象
人{
打开冰箱门的行为
装大象
关闭冰箱门的行为
}
冰箱{
打开
关闭
}
大象{
进去
}
#2、类
类是对象的抽象,就像是对象的设计大纲一样。事物:
属性
行为
类:
成员变量 对应事物的属性
成员方法 对应事物的行为
定义类:定义类其实是定义类中的成员(成员变量和成员方法)
格式:
修饰符 class 类名{
//成员变量
//成员方法
}
例如:
public class Student{
//....
}
#3、对象
对象:就是根据类来创建的实体,java里面是通过关键在new来创建对象的://就是使用new + 构造方法创建一个新的对象
类名 对象名 = new 类名();
//例如:
Student student = new Student();
课后需要认真看看对象创建和初始化过程的流程图
##3.1 匿名对象
匿名对象:就是没有名字的对象匿名对象的应用场景:
1、调用方法,仅仅需要进行一次方法调用
2、匿名对象可以做为实际参数进行传递
使用方式:
new Student().study();
好处:
匿名对象调用完毕就是垃圾,会被jvm回收
#4、变量
格式:修饰符 类型 属性名 =初始值 ;
说明:
修饰符private:该属性只能由该类的方法访问。
修饰符public:该属性可以被该类以外的方法访问
成员变量和局部变量:
1、在类中的位置不同
成员变量:在类中,方法外
局部变量:在方法内,或代码块内
2、在内存的位置也不同
成员变量:在堆中
局部变量:在栈中
3、声明周期不同
成员变量:随着对象的创建而创建,对象的消失而消失
局部变量:随着方法的调用而存在,随着方法的结束而消失
4、初始化值不同
成员变量:有默认初始值
局部变量: 没有默认初始值,必须手动初始化
5、修饰符不一样
成员变量:可以有任何修饰符
局部变量:不能有修饰符
注意:如果成员变量和局部变量的名字重复了,那么java程序有就近原则。
#5、方法
语法格式:修饰符 返回值类类型 方法名 ( 参数列表) {
方法体语句;
return 返回值;
}
修饰符:public, private, protected,默认不写
//现在我们去掉了static关键字
//有static关键字修饰:那么成员属于类成员
//无static关键字修饰:那么成员属于实例成员
#6、构造器
特征:1、名字必须与类名一样
2、不能声明返回类型,连void都不行
3、不能被static、final、synchronized、abstract、native修饰
作用:
1、创建对象
2、初始化
格式:
修饰符 类名 (参数列表,...) {
初始化语句;
}
分类:
1、隐式构造器(就是系统默认的无参构造器)
2、显示构造器(手工定义的构造器)
特点:
1、每个类至少有一个构造器
2、一个类如果没有显示定义构造器,系统会默认一个无参构造器
3、一旦手工定义了构造器,那么系统将不再默认构造器
4、构造器可以重载
#7、this关键字
1、this表示当前对象,可以调用类的属性、方法和构造器2、使用this()调用构造方法,必须放在首行
#8、javabean
1、有常用属性 ,有setter和getter方法2、有一个默认的无参构造方法
3、类是public
#9、package
1、包帮助管理大型软件系统:将语义近似的类组织到包中;解决类命名冲突的问题。2、包可以包含类和子包
3、命名方式一般是企业域名反写,例如:com.baidu.rengongzhineng
4、多层级的包使用"."拼接
5、出现在类的首行
#10、import关键字
1、为使用定义在不同包中的Java类,需用import语句来引入指定包层次下所需要的类2、import java.util.Scanner,import java.util.*
3、java.lang包下面的类都是默认导入
#11、继承
继承定义:就是将多个相同的成员变量和方法抽取到一个类中,其他类通过继承该类获取这些成员的方式,叫继承继承实现:java是通过extends关键字来实现继承
格式:class 子类 extends 父类{}
继承的好处:
1、提高代码的复用性
2、提高代码的易维护性
继承的坏处:
1、增加了代码的耦合度
继承的特点:
1、只能单继承,不支持多重继承
2、但是可以多层继承
#12、重写
重写(override):就是子类重新定义父类的方法前提条件:
1、重写的方法,必须和父类的方法具有相同的返回类型,参数列表,方法名称
2、重写的方法,访问权限不能低于父类的访问权限
3、只能重写非static的方法
4、重写方法抛出的异常,不能大于父类抛出的异常(到异常章节,会详细讲解)
5、重写可以使用@Override注解进行校验
面试题:重写(override)和重载(overload)的区别
1、重写是要有继承,因为要重写父类的方法
子类覆盖父类相同的方法,实现的逻辑不通
2、重载是在一个类完成的
方法名一样
参数类型或者个数不一样
跟返回值无关
#13、super关键字
在Java类中使用super来调用父类中的指定操作:1、super可用于访问父类中定义的属性
2、super可用于调用父类中定义的成员方法
3、super可用于在子类构造方法中调用父类的构造器
这是super必须要放在首行
注意:
1、尤其当子父类出现同名成员时,可以用super进行区分
2、super的追溯不仅限于直接父类,直到Object(Object类是所有类的父类)
3、super和this的用法相像,this代表本类对象的引用,super代表父类的内存空间的标识
super和this的区别
访问成员变量
this.成员变量 访问本类的
super.成员变量 访问父类的
访问成员方法
this.成员方法() 访问本类的
super.成员方法() 访问父类的
访问构造方法
this() 访问本类无参构造方法
super() 访问父类无参构造方法
this(...) 访问本类有参构造方法
super(...) 访问父类无参构造方法
#14、访问权限控制
* 修饰符 类内部 同一个包 不同包子类 任何地方* private Yes 不 不 不
* Default(不写) Yes Yes 不 不
* protected Yes Yes Yes 不
* public Yes Yes Yes Yes
注意:类的权限修饰符:public和默认
#15、继承中各成员之间的关系
成员变量:先在子类局部方法里找,局部找不到找成员变量,找不到再去父类成员变量找,还找不到就报错
成员方法:
先在子类找,子类里找不到再去父类找,还找不到就报错
构造方法:(创建对象和初始化)
1、子类在实例化的时候,会先访问父类的无参构造方法
2、如果父类没有无参构造方法,那就需要子类通过super关键字调用父类的有参构造方法
#16、继承中子类实例化过程
例如:class Fu{
String name;
public Fu(){
}
}
class Zi extends Fu{
int age;
public Zi(int age){
this.age = age;
}
}
new Zi(20);
执行过程:
1、调用子类有参构造方法public Zi(int age)
2、判断Zi是否有父类,如果有,先对父类的成员变量初始化
3、子类有参构造方法,又会隐式的调用父类的无参构造方法
4、初始化自己的成员变量
5、执行自己的有参构造方法
#17、多态
多态:就同一个对象在不同时刻的表现状态不一样,例如父类的引用指向自己或子类的对象多态前提条件:
1、要有继承,要有重写
普通类:
class Fu{}
class Zi extends Fu{}
//多态
Fu fu = new Zi();
抽象类:
abstract class Fu();
class Zi extends Fu{}
//多态
Fu fu = new Zi();
2、实现接口
interface Fu{}
class Zi implements Fu{}
//多态
Fu fu = new Zi();
多态中的成员访问:
1、成员变量
编译时看左边,运行时也看左边
2、构造方法
子类必须访问父类的无参构造方法
父类没有无参构造方法的话,子类就要显示的使用super来调用有参构造方法
3、成员方法
编译时看左边,运行时看右边
多态的好处:
1、提高代码的易维护性(由继承保证)
2、提高代码的可扩展性(由多态保证)
多态的弊端:
1、丢失子类的方法
#18、类型转换
多态中,子类向父类转换叫向上造型或向上转型,是安全的。父类引用转子类,需要使用强制类型转换。需要注意的是:必须能够转换,如果不能转换,就会抛ClassCastException
#19、instanceof
为了避免出现ClassCastException,我们建议使用instanceof关键字x instanceof A:检查对象x是否为类A的实例
#20、Object
Object:Object类是所有类的父类,所有的类直接或间接的继承了Object。Object常用方法:equals和toString
#21、static
static关键字修饰变量,修饰方法,代码块
* 特点:
*
* 随着类的加载而加载
* 优先于对象存在
* 修饰的成员,被所有对象所共享
* 访问权限允许时,可不创建对象,直接被类调用
static修饰的成员访问:
类名.成员
类成员: static修饰的成员
实例成员: 非static修饰的成员,因为必须实例化才能访问
静态方法:
1、使用static修饰
2、静态方法只能访问静态变量
3、方法中不能有this关键字
this代表的是当前对象,对象是通过new关键字创建的
static修饰的成员是在对象创建之前就初始化好的
#22、代码块
局部代码块,成员代码块,静态代码块作用:主要用来初始化
* 类实例化过程:
* 1、成员变量
* 2、静态代码块(只加载一次)
* 3、代码块(每次都会执行)
* 4、构造方法(每次都会执行)
#23、final
final是最终的意思,可以修饰类,方法,变量特点:
修饰的类不能被继承
修饰的方法不能被重写
修饰的变量不能被改变
注意:修饰变量时,变量只能初始化一次
* 1、要么在定义变量的时候就初始化
* 2、要么就在代码块中初始化
使用final定义常量:
一般和static配合使用,定义的常量名要大些,多个单词要用下划线分割
public static final int PAGE_SIZE=10;
#24、抽象类
将公共的方法抽取到没有具体实现的类中java中使用abstract关键字来定义抽象类:
abstact class 类名{}
抽象类的成员:
* 成员变量:既可以是变量,也可以是常量
* 构造方法:有
* 用于子类初始化
* 成员方法:
* 抽象方法
* 非抽象方法
抽象类的特点:
* 1、抽象类不能实例化
* 2、抽象类必须被继承,子类必须实现其抽象方法
* 3、抽象类可以有抽象方法,也可以没有
* 4、有抽象方法的类,必然是抽象类
案例:检查作业
/**
* 抽象类学生案例练习
*
* 学生都有个特征爱学习,然后班长给大家布置了作业
* 明天检查作业,看大家完成的情况
* 完成的可以去lol一天
* 完不成的操场跑圈儿
*
* @author Administrator
*
*/
public class Abstract04 {
public static void main(String[] args) {
Student s1 = new LingHuChong();
s1.checkHomeWork();
s1 = new YuBuQun();
s1.checkHomeWork();
}
}
abstract class Student{
//我在这里检查作业
public void checkHomeWork(){
if(doHomeWork()){
System.out.println("完成的可以去lol一天");
}
else{
System.out.println("完不成的操场跑圈儿");
}
}
//具体学生做作业
abstract boolean doHomeWork();
}
class LingHuChong extends Student{
@Override
boolean doHomeWork() {
System.out.println("令狐冲很聪明,玩儿就把作业做好了");
return true;
}
}
class XiaoLinZi extends Student{
@Override
boolean doHomeWork() {
System.out.println("小林子比较笨,怎么练习都完不成作业");
return false;
}
}
class YuBuQun extends Student{
@Override
boolean doHomeWork() {
System.out.println("最爱抄作业,但是抄啊抄还是没抄完....");
return false;
}
}
#25、接口
##25.1接口定义:
1、java中就接口是通过关键字interface来表示的interface 接口名
2、java中实现接口是通过关键字implements表示的
class 类名 implements 接口名
3、接口不能实例化,如果要实例化,是需要通过多态是实例化
接口名 变量名= new 实现类
##25.2接口的特点:
1、定义的方法默认是抽象方法默认使用:public abstract
建议自己给出
2、定义的变量,都是常量
默认使用 public final static
3、接口里不能定义构造方法
##25.3接口的继承
接口可以多重继承格式:
接口名 extends 接口1,接口2
##25.4接口的实现
接口的实现类必须实现接口的所有方法注意:一个类可以继承一个类,同时实现多个接口
子类 extends 父类 implements 接口1,接口2
*
#26.接口和抽象类的区别:
1、成员区别抽象类:
成员变量:变量,常量
成员方法:抽象方法,普通方法
构造方法:可有,用于子类初始化父类属性
接口:
成员变量:常量
成员方法:默认是抽象方法
构造方法:没有
2、关系区别:
类与类:
只能单继承
类与接口:
可以有单实现,多实现
接口与接口:
可以有单继承,多继承
3、开发过程中,建议使用接口(先在都强调的是面向接口编程)
#27、返回值类型
返回值类型:基本类型:较为简单,不讲
引用类型
类 数组 枚举 接口
如果返回类型是引用类型
普通类:那就应该返回他自己的实例,或者子类的实例
抽象类:应该返回子类实例
接口:应该返回其实现类
#28、形式参数
基本类型:较为简单,不讲引用类型
类 数组 枚举 接口
如果形式参数类型是引用类型:
普通类:那就应该返回他自己的实例,或者子类的实例
抽象类:应该返回子类实例
接口:应该返回其实现类
#29、内部类(了解)
##29.1内部类:就把类定义在别的类的内部,此类就叫内部类
根据定义的位置不同,可以分为:成员内部类
局部内部类
##29.2内部类的成员访问:
外部类访问内部类:需要实例化内部类,才能放访问内部类访问外部类:可以直接访问
##29.3内部类实例化方式:
非静态内部类外部类.内部类 变量名 = new 外部类().new 内部类();
静态内部类:
外部类.内部类 变量名 = new 外部类.内部类();
##29.4局部内部类:
定义在方法内部,或者代码块内部局部内部类访问局部变量时,需要注意:
局部变量必须是final类型:
因为局部变量随着方法的结束而消失,而对象的引用不会立即消失,所以需要保证局部变量的生命周期。
##29.5匿名内部类(掌握)
定义:其实内部类的简化方式前提:有类(普通类或抽象类)或者接口
格式:
new 类名或接口(){
//重写方法
}
本质:其实就是继承了某个类或者实现某个接口的子类的匿名对象
开发中使用:
当我们看到一个参数类型是个抽象类或者接口时,就要知道需要传递其子类或实现类
如果这个类的方法仅仅需要调用一次,我们就使用匿名内部类来实现。
interface Inter {
void show();
}
class Outer {
//补齐代码
public static Inter method(){
return new Inter(){
void show(){
System.out.println("HelloWorld");
}
};
}
}
class OuterDemo {
public static void main(String[] args) {
Outer.method().show(); //"HelloWorld"
}
}