面向对象
一. 类和对象
a) 定义
类:是对一类事物的描述,是概念上的抽象的定义。例如汽车的设计图纸,不占用内存空间
对象:实际存在的该类的每个个体。例如:根据汽车的设计图纸生产出来的占内存空间。
万物皆对象
b) 语法结构
修饰符class 类名{
属性; 名词:大小、颜色、形状
方法; 动词:跑 、刹车、加速
}
主类:包含main方法的类,修饰符为public。一个.java文件中只能有一个被public修饰的类,且public修饰的类的类 名与该文件相同
建议:一个.java文件中只包含一个类的定义,对象的创建即调用
例:
public class Car{
}
c) 构造方法
i. 语法结构
修饰符 类名(参数列表){
}
例子:
public Cat(){
}
ii. 注意事项
1. 没有返回值类型
2. 方法名与类名相同
3. 其实JVM默认提供了一个无参的构造方法,如果没有显示写出构造方法,就会自动调用默认的无参构造方法。如果显示的写出构造方法,则JVM不再提供,调用程序必须按照该构造方法的形式进行调用。
4. 构造方法可以有参数,一般给出的参数与该类的属性一一对应。
iii. 作用:
1. 开辟内存空间
2. 在构造方法中初始化成员属性和其他初始化工作
iv. 构造方法重载
public class Car{
int size;
String color;
//空构造方法
public Car(){
}
//有参构造方法
public Car(int size){
this.size=size; 一般形参和成员变量命名相同,为区别形参和成员变量,使用this。this指的是该对象本身。
}
//包含所有属性的构造方法
public Car(int size,String color){
this.size=size;
this.color=color;
}
}
d) 对象的创建与调用
i. 创建语法
类型 对象 = new 类的构造方法([参数]);
Car myCar = new Car();
ii. 调用
对象名.成员变量、对象名.成员方法
例:myCar.color = “blue”;
myCar.run();
System.out.println(myCar.size);
e) 面向过程与面向对象的区别
f) 类图
g) 类变量和类方法(static关键字的用法)
a. 类变量
定义:该类的所有对象所共用的变量 全局变量
区别:普通成员变量存储的是单个对象的值,不同的对象,其值可以不同。而类变量属于该类所有,如果该类的一个对象修改了其值,则其他该类的对象相关值也会改变
作用:用来表示该类的对象所共有的属性。例如:中国人的国际都是中国人。
例:
//统计该类一共创建了多少个对象
public class Car{
public static int total;//类变量用来统计对象的个数
public Car(){
total++;
System.out.println(“当前第”+total+“辆车出厂。”);
}
}
public class Test{
public static void main(String[ ]args{
Car car1 = new Car(); 当前第一辆车出厂
Car car2 = new Car(); 当前第二辆车出厂
}
}
h) 注意事项:可以直接用“类名.类变量”方式使用
System.out.println(Car.total);
b. 类方法
定义:
区别:修饰符比普通成员方法多static;普通成员方法调用“对象名.方法名()”,类方法调用“类名.方法名()”。
使用场景:不方便创建对象的地方,没必要没使用一次该方法就创建一次该类的对象。例如Math类
注意事项:main方法是static方法;类方法中所调用的成员必须是static成员;
例如:public calss Car{
static float size;
public static void run(){
System.out.println(size);
}
}
类方法可以直接用“类名.方法名()”方式使用。
c. 静态代码块
例:public class Car{
static float size;
static{
size=1; 静态代码块,比构造方法执行的早
}
public Car(){
}
}
二. 封装
a.作用:隐藏内容实现:提供安全;容易修改代码,方便后期维护
b.使用场景:一般不涉及继承或实现的类,尽量进行封装
c.步骤:
第一步:私有化成员变量;
private String name;
第二步:给出对应的set和get方法;
public String getName() {
return name;}
public void setName(String name) {
this.name = name;
}
第三步:在set和get方法中添加安全判断条件
public void setName(String name) {
if(nume==null){
System.out.println(“名字不能为空”)
}else{
this.name = name;} }
第四步:替换构造方法中的“this成员变量 = 形参”成对应的set方法
public Car(float size,String color,String xz){
setColor(color);
setSize(size);
}
特殊用法
实体类只包含set get 方法
三. 继承
1. 概念:父类(超类、基类);子类(派生类、拓展类)
2. 关系:is a
3. 使用场景:项目中出现多个类,这些类中出现了重复代码,且这些类可以找到一个共同的父类。可以把这些类中的重复代码放到父类中实现,子类继承父类即可。
4. 继承中出现的关键字:extends
5. 例子
public class People {
// 属性
String name;
String sex;
// 方法
public void sleep() {
System.out.println("睡觉");
}
public void eat() {
System.out.println("吃饭");
}
}
public class Student extends People {
// 属性
String sNo;// 学号
// 方法
public void study() {
System.out.println("学习");
}
public class Worker extends People{
String wNo;
public void work(){
System.out.println("工作");
}
}
子类可以继承父类的属性和方法(除了父类私有的 private)
public static void main(String[] args) {
Student student = new Student();
student.name = "张三"; 父类的属性
student.sex = "男"; 子类的属性
student.sNo = "123"; 子类的属性
student.study(); 父类的方法
student.sleep(); 父类的方法
}
6. 注意事项:
a. java中所有类的父类默认的都是Object类;从Object类中继承过来的常见的方法有 equals(Object obj)、toString
b. java中只能出现单继承,即每个类只能有一个父类,但是一个父类可以有多个子类;
c. 子类中重写后的方法,其修饰符不能比父类严格;
d. 子类中重写后的方法,其抛出的异常只能是父类方法抛出异常本身或子类
7. Super关键字
a. 使用场景:子类中调用父类成员使用super关键字
b. 例:
c. 继承中的构造方法
创建对象就调用
子类不会继承父类的构造方法;但是在创建子类对象的时候 先调用父类的构造方法,再调用子类的构造方法;父类的构造方法一旦重载,且不再有无参的构造方法,则子类继承出错;子类继承父类,如果不想出错:
- 父类中重载构造方法时给出无参构造方法,
- 在子类的构造方法中 显示调用父类的有参构造方法,调用方式如下:
public Student(){
super(“小明”,”男”); 在构造方法中super只能出现在第一行
System.out.println();
}
四. 多态
1、 描述:代码中出现了重名现象。方法多态、对象多态。
2、 方法重载OverLoad
同一个类,方法名相同,参数列表不同,与返回值无关。
构造方法可以重载。
3、 方法重写
a、 描述:发生在父类和子类之间,子类中出现了与父类同名且参数列表相同、返回值类型相同的方法。
b、 toString()方法
该方法是继承Object类的方法,直接调用输出:
重写toString():
public String toString() {
return "Door [height=" + height + "]";
}
c、 equals()方法
i、 面试题:==与equals()的区别?
==:判断两个引用变量是否指向同一个对象(内存地址)
equals():比较的是两个对象的内容是否相等
ii、 重写equals
public boolean equals(Object obj) { 可以是任意引用类型
if (this == obj){
return true; } 查看是否是对象本身
if (obj == null) {
return false; } 查看被比较对象是否为空
if (getClass() != obj.getClass()){
return false; } 保证比较的两个对象类型相同
Door other = (Door) obj;强制转换类型,下转型
if (height != other.height) {
return false; 判断属性是否一样
}
return true;
}
d、 建议:重写后的方法前都添加 @Override,主要是防止编写错误
4、 转型
可以理解为引用数据类型的类型转换
instanceof 运算符是用来在运行时指出对象是否是特定类的一个实例。
a、 上转型:子转父
b、 下转型:
5、 final关键字
a. 修饰类:该类不能被继承
b. 修饰方法:该方法不能被重写
c. 修饰变量:该变量变为常量,一般大写;通常和static一起用,变成静态常量
五. 接口和抽象类
1. 抽象类
a) 描述:没有具体的方法来求解。例如:形状类,但是形状具有面积,但是不知道什么具体形状的情况下是无法求面积的,三角形、正方形、圆形是形状,可以根据本身的形状特征来求其面积
b) 关键字:abstract,该关键字一般只能放到方法和类的前面
c) 抽象方法:方法定义修饰符有abstract,但是该方法没有方法体。
其他修饰符abstract 返回值类型 方法名(参数列表);
包含抽象方法的类,一定是抽象类。该类前面有abstract修饰符
d) 例子
public abstract class XingZhuang {
double area;//面积
public abstract double getArea();//获取面积
}
public class Yuan extends XingZhuang {
double r;
public Yuan( double r){
this.r = r;
}
//复写抽象类中的方法 子类继承抽象类一定要实现抽象方法
public double getArea(){
return r*r*Math.PI;
}
}
public class ZhengFang extends XingZhuang {
double bian;//定义正方形边长
@Override
public double getArea() { 复写抽象类中的方法
area = bian*bian;
return area;
}
}
e) 注意事项
a. 抽象类是一个类
b. 包含抽象方法的类一定是抽象类,但是抽象类不一定包含抽象方法;
c. 抽象类不能被实例化,即不能new一个抽象类
d. 子类继承抽象类,必须要重写抽象类中的抽象方法,除非子类也是抽象类。抽象类的抽象方法是在子类中实现的
2. 接口
a) 使用场景:为了解决java中的单继承问题,可以使用接口来实现。具体的某个方法不适合把它单独定义成一个类,例如:飞,鸟类中的某些动物具有飞行的动作,昆虫中的某些动物也具有飞行动作,飞机类也具有飞行的动作;但是为了减少代码重复量,就把“飞”防盗一个接口中。
b) 语法结构
public interface Fly {
void fly(); 没有方法体,其实是一个抽象方法
}
接口中可以有属性但是属性的默认修饰符是 public static final ,即接口的成员变量只能是静态常量,这三个修饰符可以不写;接口中的方法默认修饰符是 public abstract,这两个修饰符也可以不写。接口中只能包含静态常量和抽象方法。
c) 例子
public class Niao{
int flyNum;
}
public class KunChong{
int legNum;
}
public class Ying extends Niao implements Fly{
public class TuoNiao extends Niao{
}
}
d) 实现多个接口:多个接口之间用“,”隔开。
e) 接口继承接口:extends
f) 注意事项:
a. 实现接口的类一定要实现接口中的所有抽象方法;如果不实现,那么该类一定是个抽象类。
b. 一个类可以实现多个接口。
c. 接口中只能包含静态常量和抽象方法
3. 抽象类和接口相同点和不同点
a.接口和抽象类都不能被实例化。只能被其他类实现和继承。
b.接口和抽象类都可以包含抽象方法,实现接口和抽象类的类都
c.必须实现这些抽象方法,否则实现的类就是抽象类。