面向对象概念
1.面向对象是基于面向过程的一种编程思想
a.面向过程强调的是每个功能的步骤
b.面向过程强调的是对象,调用这个对象去完成功能
类和对象的关系
1.类是java最基本的单位
a.可以把事物抽象成具体的类
事物的属性 类中的成员变量
事物的行为 类中的成员方法
2.对象的创建
格式: 类名 对象名 = new 类名();
创建对象就是调用类中的构造方法
3.成员变量和局部变量的不同
a.成员变量在类内,方法外
局部变量在方法中,方法声明上(形式参数)
b.成员变量在堆内存中
局部变量在栈内存中
c.成员变量随着对象的创建而创建,生命周期长
局部变量随着方法的调用而创建
d.成员变量有初始的默认值 String null; int 0; double 0.0;
局部变量没有初始的默认值
2.1 匿名对象
匿名对象是指创建对象时,只创建对象,没有把对象的地址值赋给某个变量
特点: 创建匿名对象可以直接使用,没有变量名
匿名对象在没有其指定引用变量时只能使用一次
@匿名对象可以作为方法的参数或者返回值使用
面向对象的三大特征:封装,继承,多态
1.封装
private关键字修饰的成员只能在本类中使用
封装的原则:
a.将不需要对外提供的内容隐藏起来
b.对外提供公共方法对其进行访问(成员变量private,对外公共的get/set方法)
c.通过方法控制成员变量的操作,提高了安全性
d.把代码用方法进行封装,提高了代码的复用性
1.2
构造方法
作用:给对象的数据进行初始化
格式特点:
方法名和类名一样
没有返回值,没有返回值类型
格式: 修饰符 类名(参数列表){};
2. 继承
2.1 格式: class 子类 extends 父类{}
从类和类的关系来看,子类属于父类的一种才会继承
父类抽取了共性的内容,子类在父类的基础上扩展新的新的属性和行为
子类拥有所有父类的属性和行为,无需重新定义,可以直接使用父类非私有的成员
在程序中创建对象调用方法时,先查找子类中有没有,有用子类,没有查找父类,有用父类的,没有编译报错
继承的特点:Java支持单继承
Java支持多层继承
父类定义了继承数中的共性内容,子类定义了该类的个性内容
结合多态,能使用父类就使用父类,提高程序的扩展性
2.2 方法重写
概念: 子类中出现了和父类中一模一样的方法,称为方法重写
方法重写的注意事项:
a,父类中的私有方法子类继承不了,也重写不了
b,子类重写父类的方法,必须保证权限大于父类
public:公共的
protected:受保护的
default:默认的,不写就是默认的
private:私有的
public>proctected>private;都要一样
c,写法上注意,必须一模一样:方法的返回值类型,方法名,参数列表都要一样
子类如果有和父类同名的私有方法,不是方法重写,相当于重新定义了一个私有的方法
this和super
每次我们创建子类对象时,都会先创建其父类对象,再创建子类对象
调用普通成员/普通方法:
this.成员变量 访问本类对象的成员变量
super.成员变量 访问父类对象的成员变量
this.成员方法() 访问本类对象的成员方法
super.成员方法() 访问父类对象的成员方法
this(其他参数); 访问本类其他的构造方法
super(其他参数); 访问父类其他的构造方法
子类中每个构造方法都有默认的super();
子类对象创建过程的细节
1.this(参数)和super(参数),都必须写在第一行,不能同时存在
2.子类中所有的构造方法,无论重载多少个,super(参数)语句必须是构造方法第一行;
如果父类有多个构造方法,子类任意调用一个就可以;
3.无论如何,子类的所有构造方法,必须直接或间接调用到父类的构造方法.
子类的构造方法,什么都不写,默认的构造方法第一行super();
2.3 抽象类
包含抽象方法的类称之为抽象类,也需要被abstract修饰
格式:
修饰符 abstract 类名{}
抽象类的使用:
1.抽象类无法创建对象:Cannot instantiate the type Employee
a.在某些特定的情况,一个类不想让其他人创建对象使用,可以定义为抽象类.
b.抽象类中包含了抽象方法,抽象方法没有方法体,创建对象使用方法没有意义
2.创建抽象类的子类,继承抽象类,重写抽象类中抽象方法,创建子类对象使用
抽象类的细节:
1.抽象类可以继承别的类吗,可以 Object
2.抽象类可以定义普通的方法,可以让子类继承使用
3.抽象类中也可以定义构造方法
a.创建对象使用
b.带参数构造为成员变量赋值
4.抽象类中,有多个抽象方法, 子类继承抽象类,重写全部的抽象方法;否则子类还是一个抽象类
5.抽象类中也可以不包含抽象方法,不让别人使用
3.多态
3.1 接口
接口:是功能(方法)的集合
接口也是使用.java文件,编译之后产生的也是.class文件
定义接口使用关键字interface
接口定义的格式:
修饰符 interface 接口名{
常量;
抽象方法;
}
接口中的变量:叫做常量,也是为抽象方法服务
有固定的修饰符:public static final 数据类型 常量名 = 常量值;
public:公共的,在当前项目中都可以使用
static:静态的,我们通过类名/接口名不用创建对象,直接使用
final:最终的,固定住变量的值,变量的值就不能改变了,就是一个常量
常量名的定义规则:所有的字母都使用大写英文,多个单词使用下划线连接
接口中的方法都是抽象方法
有固定的修饰符:public abstract 返回值类型 方法名(参数列表);
常量和方法的修饰符,可以省略不写,不写也是以上修饰符;建议写出增强阅读性
接口的使用:
1.接口不能创建对象
2.创建接口的实现类(子类),实现(继承)接口,重写接口中的抽象方法,创建实现类对象使用
接口中成员的特点
1、接口中可以定义变量,但是变量必须有固定的修饰符修饰,public static final 所以接口中的变量也称之为常量,其值不能改变。后面我们会讲解static与final关键字
2、接口中可以定义方法,方法也有固定的修饰符,public abstract
3、接口不可以创建对象。
4、子类必须覆盖掉接口中所有的抽象方法后,子类才可以实例化。否则子类是一个抽象类。
接口的特点:
1.java中支持一个类可以实现多个接口
多个接口如果有一样的方法,没有方法体
实现类实现类接口,重写了抽象方法,就相当于重写多个接口中的方法
不会产生不确定性
接口就是一个干爹,可以有多个
2.java中支持类继承一个类的同时,可以实现多个接口
实现类必须重写父类和接口中所有抽象方法
一个人只有一个亲爹,但是可以有多个干爹
3.接口与接口之间是继承的关系,一个接口可以继承多个接口;就相当于计算多个接口的并集
接口C继承了接口A与B,C就中就相当于包含了接口A,B,C中所有的抽象方法
总结:
类与类之间关系:继承
public class 子类 extends 父类{}
类与接口之间关系:实现
public class 实现类 implments 接口{}
接口与接口之间的关系:继承
public interface 接口 extends 接口1,接口2...{}
接口不可以继承变量(常量)
多态:父类的引用变量变量指向了子类的对象
多态的格式:
父类/接口 变量名 = new 子类/实现类();
多态的特点:
使用的是子类重写后的方法
多态有多个子类,调用的是每个子类重写后的方法
多态中成员的特点:
编译:
成员变量:父类中有编译成功,父类没有编译失败
成员方法:父类中有编译成功,父类没有编译失败
运行:
成员变量:运行的是父类的变量
成员方法:运行的是子类重写后的方法
多态的好处和弊端:
好处:扩展性强,可以给父类变量赋值不同的子类,调用的是每个子类重写后的方法
弊端:表现是父类的形态,无法使用子类特有的成员
我们可以使用父类作为方法的参数和返回值类型
向上转型:父类的引用变量指向了子类的对象
多态本身就是向上转型
格式:
父类 变量名 = new 子类();
就像默认类型转换:把小的数据类型直接赋值给大的类型
int a = 10;
double d = a;
向下转型:把多态的父类变量强制转换为子类
前提必须是多态
格式:
子类 变量名 = (子类)父类的变量名;
就像强制类型转换:把大的数据类型,强制转换为小的类型
double d = 8.8;
int a = (int)d;
instanceof关键字:判断某个对象是否属于某种数据类型
格式:
boolean b = 对象 instanceof 数据类型;
使用前提:必须有继承或者实现关系
面向对象杂
static关键字
static是静态修饰符,一般修饰成员;被static修饰的成员属于类,不属于单个这个类的某个对象。
static的特点:
1,同一个类中,静态成员只能访问静态成员,静态成员优先非静态成员存储在内存中,非静态成员可以访问静态成员
2,main方法为静态方法仅仅作为程序的入口,它不属于任何一个对象,可以定义在任意类中
代码块:被{}包裹起来的代码
局部代码块:定义在方法中
使用时注意变量的作用域
构造代码块:定义在成员位置(类中,方法外)
构造代码块执行优先于构造方法
创建一次对象,就会执行一次构造代码块
作用:
1,可以给成员变量赋指定的值
2,可以把所有构造方法中的共享内容,提取到构造代码块中
静态代码块:定义在成员位置,被static修饰
只有访问了类中的内容,就会执行
不管创建了多少次对象,终身只会执行一次,最先执行(优先于构造代码块执行)
静态的属于类,不属于某个对象
作用:
1,可以给静态的成员变量赋值
2,可以定义一些初始化的数据(数据库)
多态中,成员的特点:
编译:
都看等号左边的父类,父类有编译成功,父类没有编译失败
运行:
成员变量:运行全看父类
成员方法:非静态的方法,运行子类重写的方法
静态的方法,运行父类中的静态方法
final修饰类不可以被继承,但是可以继承其他类。
使用方式没有变化,可以继承其他的类,也可以实现其他接口,也可以创建对象,调用类中的方法
被final修饰的类,称之为太监类
final修饰的方法可以被继承使用,不可以被重写(是一个最终方法),
但父类中没有被final修饰的方法,子类重写后可以加final修饰。
局部变量:定义在方法中的变量(方法声明上,方法内部,语句中)
final修饰局部变量: 一次赋值,终身不变
final修饰基本类型的局部变量:是一个常量,值不能改变
final修饰引用数据类型的局部变量:地址值不能改变,但是对象的属性可以变化
引用数据类型赋的值是对象的地址值,所以final固定住这个地址值
final修饰的成员变量:必须在创建对象前赋值,否则报错
成员变量的默认值,不是final修饰的变量的值,必须给final修饰的变量赋值使用
有两种给final修饰的变量赋值方式
1.直接赋值:定义变量的时候,直接给出初始化的值
2.可以使用构造方法,构造代码块给final修饰成员变量赋值
注意:不管直接赋值,还是使用构造方法,或者构造代码块赋值,final修饰的成员变量只能赋值一次;
包 归纳一下:在日常开发过程中,编写的类、方法、成员变量的访问
要想仅能在本类中访问使用private修饰;
要想本包中的类都可以访问不加修饰符即可(默认);
要想本包中的类与其他包中的子类可以访问使用protected修饰
要想本项目所有包中的所有类都可以访问使用public修饰。
注意:
一个文件中可以定义多个类(不建议)只能有一个public修饰的类。
如果类用public修饰类,则类名必须与文件名相同。
内部类:定义在其他类内部的类
分类:
成员内部类:定义在其他类的成员位置的类(类中,方法外)
局部内部类:定义在其他类的方法中的类
我们定义内部类时,就是一个正常定义类的过程,同样包含各种修饰符、继承与实现关系等。
在内部类中可以直接访问外部类的所有成员。
成员内部类的定义格式:
修饰符 class 外部类{
修饰符 class 成员内部类{
成员变量;
成员方法;
}
}
成员内部类的使用格式:
外部类名.内部类名 变量名 = new 外部类名().new内部类名();
注意:
Outer$Inner.class:成员内部类编译生成的class文件的格式
局部内部类(了解):定义在其他类的方法中
定义格式:
修饰符 class 外部类名{
修饰符 返回值类型 外部类方法名(参数){
(final) class 局部内部类名{
成员变量;
成员方法;
}
}
局部内部类名 变量名 = new 局部内部类名();
变量名.成员变量
变量名.成员方法();
}
使用格式:
相当于局部变量,作用域只在方法中有效
必须在定义完类,立即创建对象使用
编译之后产生的class文件
Outer$1Inner.class
匿名内部类:没有名字的局部内部类
作用:简化操作
把定义子类,继承父类重写父类的方法,创建子类对象合成一步完成
把定义实现类,实现接口重写接口中的方法,创建实现类对象合成一步完成
格式:结果就是一个子类/实现类的对象,没有名字就匿名
new 父类/接口(){
重写父类/接口中的方法;
};
new Fly(){
public void fly(){
System.out.println("动物在飞!");
}
};
以上代码就是创建接口Fly的实现类过程;相当于new Ying()