类和对象

定义

类的定义:
public class 类名{
//成员变量的定义
//成员方法的定义(没有static关键字)
}

例如:
public class Phone{
//成员变量的定义
String brand;
int price;
//成员方法的定义(没有static关键字)
public void call(){
System.out.printIn("打电话");
}
public void sendPassage(){
System.out.printIn("发短信");
}
}

创建对象:类名 对象=new 类名();
例如:Phone p=new Phone();

在c++中,不重载<<运算符时直接输出对象会报错,但java中可以直接输出对象,得到的是对象的地址,在编译器中实际输出应该为对象的包名.类名@对象的具体地址。

成员变量和局部变量

区别 成员变量 局部变量
类中位置不同 类中方法外 方法内或声明上
内存中位置不同 堆内存 栈内存
生命周期不同 随对象存在和消失 随方法调用存在和消失
初始化值不同 有默认初始值 没有默认的初始化值,必须先定义,赋值,才能够使用

封装

针对不想在类外直接访问的变量或方法,可以通过将public关键字替换为private(变量省略关键字时默认是public,需要在数据类型前面添加private关键字),体现类的封装。

封装的好处:

  • 通过方法来控制成员变量的操作,提高代码的安全性
  • 把代码用方法进行封装,提高了代码的复用性

this关键字

java中的this关键字和c++的this指针是同一个作用,用于解决局部变量隐藏成员变量,书写格式如下:

this.变量名
例如:this.name

this修饰的变量用于指代成员变量:

  • 方法的形参如果和成员变量同名,不带this修饰的变量指的是形参而不是成员变量
  • 方法的形参没有和成员变量同名,不带this修饰的变量指的是成员变量

this代表所在类的对象引用,方法被哪个对象引用,this就代表哪个对象

构造方法

public class 类名{
//构造方法写在类内
修饰符 类名(参数){

}
}

和c++一样,当代码给出了任意构造方法后,系统将不再自动提供默认的无参构造

继承

面向对象三大特征之一,可以使子类具有父类的属性和方法,还可以在子类中重新定义,追加属性和方法

格式:public class 子类名 extends 父类名{}
如:public class Student extends Person{}
表示子类Student继承自父类Person
  • 优点:提高代码的复用性,提高代码的维护性
  • 弊端:让类和类产生了关系,父类改变时子类不得不改变

继承中变量的访问特点:

在子类方法中访问一个变量:

  1. 在子类局部范围找
  2. 在子类成员范围找
  3. 在父类成员范围找
  4. 否则报错(不考虑父类的父类的继承)

继承中构造方法的访问特点:

子类中所有的构造方法默认都会访问父类中无参的构造方法,理由如下:

  • 子类会继承父类中的数据,可能还会使用父类的数据,所以要先初始化父类数据
  • 每一个子类构造方法的第一条语句默认都是:super()

如果父类中没有无参构造方法,只有带参构造方法:

  • 通过使用super关键字去显示的调用父类的带参构造方法
  • 在父类中自己提供一个无参构造方法(推荐)

继承中成员方法的访问特点:

通过子类对象访问一个方法:

  • 子类成员范围找
  • 父类成员范围找
  • 否则报错(不考虑父类的父类的继承)

继承的注意事项

  • java中类只支持单继承,不支持多继承
  • java中类支持多层继承,但变量和成员方法不考虑父类的父类

方法重写

子类中出现了和父类中一样的方法声明,但功能子类需要具有特有的内容时,可以重写父类中的方法,这样,即沿袭了父类的功能,又定义了子类的特有内容

注意事项:

私有方法是不能被重写的(类似c++父类私有函数在子类不可见)

子类方法访问权限不能更低(public>默认>私有)

@Override是一个方法重写的注解,可以帮助检查重写方法的方法声明的正确性

super关键字

super关键字的用法和this关键字的用法相似

  • this:代表本类对象的引用
  • super:代表父类存储空间的标识(可以理解为父类对象引用)
关键字 访问成员变量 访问构造方法 访问成员方法
this this.成员变量,访问本类成员变量 this(…),访问本类构造方法 this.成员方法(…),访问本类成员方法
super super.成员变量,访问父类成员变量 super(…),访问父类构造方法 super.成员方法,访问父类成员方法

多态

多态分为具体类多态,抽象类多态,接口多态

多态的前提和实现

  • 有继承/实现关系
  • 有方法重写
  • 有父(类/接口)引用指向(子/实现)类对象

成员的访问特点

成员变量使用父类成员变量,成员方法使用子类重写的父类成员方法,如:

Animal a=new Cat();

对于Animal类中不存在,但Cat类中存在的成员变量是无法使用的,因为创建的变量a是Animal类;但在Cat类中重写了Animal类的成员方法后,使用该成员方法时,将会调用Cat类重写之后的成员方法。

两者存在区别的原因是由于成员方法有重写而成员变量没有重写,对于Animal类和Cat类继承下来的同一个方法入口构成了类似重载的关系

多态的好处和弊端

好处:提高了程序的扩展性——定义方法的时候,使用父类作为参数,在使用的时候,可以使用具体的子类型传参

弊端:不能使用子类的特有功能

多态中的转型

  1. 向上转型——Animal a=new Cat();
    • 从子到父
    • 父类引用指向子类对象
  2. 向下转型——Cat c=(Cat)a;
    • 从父到子
    • 父类引用转为子类对象

抽象类

一个没有方法体的方法该定义为抽象方法,类中如果有抽象方法,该类必须定义为抽象类

java中抽象使用abstract关键字修饰:

public abstract class Animal{
//含有抽象方法的类必须为抽象类
public abstract void shout();
//抽象方法必须位于抽象类中
}

抽象类的特点

  • 抽象类和抽象方法必须使用abstract修饰
  • 抽象类中不一定有抽象方法,但有抽象方法的一定是抽象类
  • 抽象类不能实例化,即不能创建对象,它只能通过子类对象实例化
  • 抽象类的子类要么重写抽象类中所有抽象方法,要么是抽象类

抽象类的成员特点

  • 成员变量:可以是变量也可以是常量
  • 构造方法:有构造方法,但不能实例化,构造方法用于子类访问父类数据的初始化
  • 成员方法:可以有抽象方法,限定子类必须具有某些方法,也可以有非抽象方法,用于提高代码复用性