面向对象的三大特性
一、封装
概念
将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问。
优点
-
提高程序的安全性,保护数据;
-
隐藏代码的实现细节;
-
统一接口;
-
提高系统的可维护性。
高内聚低耦合
(高)类的内部数据操作细节由自己完成。
(低)仅暴露少量的方法给外部使用。
this关键字(代表当前对象)
this.属性:操作当前对象的属性。
this.方法:调用当前对象的方法。
将属性私有化,使用set/get方法
Demo.java
public class Demo {
public static void main(String[] args) {
Person person = new Person();
person.setName("littleRed");
person.setSex("女");
person.setAge(22);
System.out.println(person.toString()); Person{name='littleRed', age=22, sex='女'}
}
}
Person.java
public class Person {
private String name; //姓名
private int age; //年龄
private String sex; //性别
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", sex='" + sex + '\'' +
'}';
}
}
二、继承
概念
继承是类与类的一种关系,子类 extends 父类,一个子类只能有一个父类。
优点
子类拥有父类的所有属性和方法(除了private修饰的属性不能拥有)从而实现了实现代码的复用。
Person.java
public class Person {
public String name = "脆皮五花肉"; //姓名=脆皮五花肉
public void print(){
System.out.println("打印父类Person");
}
}
Student.java
public class Student extends Person{
//此时Student并没有声明 变量name 和 方法print()
//但已经继承了父类Person的 属性name 和 方法print()
}
Demo.java
public class Demo {
public static void main(String[] args) {
Student student = new Student();
System.out.println(student.name); 脆皮五花肉
student.print(); 打印父类Person
}
}
重写
子类在继承父类方法后可重新编写覆盖方法。
注意:返回类型,方法名,参数类型及个数 都需要和继承的父类方法相同。
重载和重写的区别:
方法重载:在同一个类中处理不同数据的多个相同方法名的多态手段。
方法重写:相对继承而言,子类中对父类已经存在的方法进行区别化的修改。
Person.java
public class Person {
public void print(){
System.out.println("打印父类Person");
}
}
Student.java
public class Student extends Person{
//对父类的print方法进行重写
public void print(){
System.out.println("打印子类Student");
}
}
Demo.java
public class Demo {
public static void main(String[] args) {
Student student = new Student();
student.print(); 打印子类Student
}
}
Object类
java中所有的类都默认或间接继承Object类。
一般使用 “对象.” 所弹出的所有方法都是继承于Object类。
super关键字
在对象的内部使用,可以代表父类对象。
Person.java
public class Person { public void print(){ System.out.println("打印父类Person"); }}
Student.java
public class Student extends Person{ //子类的构造方法 public Student(){ print(); //调用子类Student的print() this.print(); //调用当前类的print() super.print(); //调用父类Person的print() } public void print(){ System.out.println("打印子类Student"); }}
Demo.java
public class Demo { public static void main(String[] args) { //super只能出现在子类的 方法 或 构造方法 中 //此处无法使用super获取 父类Person 的 print方法 Student student = new Student(); 打印子类Student 打印子类Student 打印父类Person }}
构造方法
Person.java
public class Person { //父类的构造方法 public Person(){ System.out.println("Person的无参构造方法已执行"); }}
Student.java
public class Student extends Person{ //子类的构造方法 public Student(){ //隐藏代码:super(); //若父类只有有参构造方法,则必须在子类构造方法中实现,否则无法使用子类构造方法 super();//调用了父类的构造器,且必须在子类构造器的第一行 System.out.println("Student的无参构造方法已执行"); }}
Demo.java
public class Demo { public static void main(String[] args) { //在子类构造方法中 super 和 this 不能同时调用该子类的其他构造方法 Student student = new Student(); }}
final关键字
- final 修饰类,则该类不允许被继承。
- final 修饰方法,则该方法不允许被覆盖(重写)。
- final 修饰属性,则必须将属性初始化或在构造方法中赋值,且后续无法再修改。
三、多态
概念
同一方法可以根据发送对象的不同而采用多种不同的行为方式。
一个对象的实际类型是确定的,但可以指向对象的引用类型有很多。(仅存在于父子类之间)
注意:多态是方法的多态,属性没有多态性。
优点
-
提高了代码的维护性(继承保证)。
-
提高了代码的扩展性(由多态保证)。
条件
-
类之间有继承关系。
-
子类重写父类的方法。
-
父类引用指向子类对象。
引用多态
Person.java
public class Person {
}
Student.java
public class Student extends Person{
}
Demo.java
public class Demo {
public static void main(String[] args) {
//一个对象的实际类型是确定的,例如 new Student() , new Person()
//而一个对象的引用类型可以是自身类型,也可以是父类类型
Student student = new Student();
Person person = new Student();//父类Person引用 指向 子类Student 对象
}
}
方法多态
- 如果父类的方法有static关键字,则方法的多态无法实现。
Person.java
public class Person {
public static void sleep(){
//将父类方法改为static修饰
System.out.println("人一天至少需要睡够8个小时");
}
}
Student.java
public class Student extends Person{
public static void sleep(){
//子类重写了父类的方法
System.out.println("学生一天睡不够8个小时");
}
}
Demo.java
public class Demo {
public static void main(String[] args) {
Student student = new Student();
Person person = new Student();//父类Person引用 指向 子类Student 对象
student.sleep(); 学生一天睡不够8个小时
person.sleep(); 人一天至少需要睡够8个小时
}
}
- 如果父类的方法没有static关键字,则父类引用类型的对象调用的方法将具有多态性。
Person.java
public class Person {
public void sleep(){
System.out.println("人一天至少需要睡够8个小时");
}
}
Student.java
public class Student extends Person{
public void sleep(){
//子类重写了父类的方法
System.out.println("学生一天睡不够8个小时");
}
public void eat(){
//子类独立的方法
System.out.println("学生喜欢吃好吃的");
}
}
Demo.java
public class Demo {
public static void main(String[] args) {
Student student = new Student();
Person person = new Student();//此时的 person 是 Student类 new出来的实例
student.sleep(); 学生一天睡不够8个小时
// person 将执行被重写的方法
person.sleep(); 学生一天睡不够8个小时
//对象能执行哪些方法,取决于等号左边的引用类型
student.eat(); 学生喜欢吃好吃的
//由于 eat() 是子类 Student 独有的方法
//若不强制转换引用类型,则 person 无法执行 eat()
((Student)person).eat(); 学生喜欢吃好吃的
}
}
小结
静态方法属于类的方法,非静态方法属于对象的方法。
静态方法在类生成的时候已经实现,非静态方法在对象生成的时候才实现。
当有static时,Person person 调用的是Person类的方法。
当没有static时,Person person 调用的是Student类new出来的对象的方法。
instanceof运算符
主要作用是测试它左边的对象是否为它右边的类的实例。
public class Demo {
public static void main(String[] args) {
Object object = new Student(); //实际类型是 Student
//引用类型与实际类型一致,返回true
System.out.println(object instanceof Student); true
//引用类型Person 是 实际类型Student 的父类,返回true
System.out.println(object instanceof Person); true
//引用类型Object 是 实际类型Student 的父类,返回true
System.out.println(object instanceof Object); true
//引用类型Teacher 不是 实际类型Student 的父类,返回true
System.out.println(object instanceof Teacher); true
//引用类型String 不是 实际类型Student 的父类,返回true
System.out.println(object instanceof String); true
}
}