Java面向对象的三大特性(封装、继承、多态)
封装
- 程序设计要向“高内聚,低耦合”方向努力。高内聚就是类的内部数据操作细节自己完成,不允许外部干涉;低耦合就是暴露少量的方法给外部使用
- 封装:数据细节的隐藏,通常要禁止直接访问一个对象中数据的实际表示,而是通过操作接口来访问,这称作信息隐藏
- 在编程时设计属性为私有,然后编写get/set方法对外调用
package oop.demo02;
//创建一个类,将对象的属性和方法封装到这个类中
public class Demo01 {
//属性私有:private,只能在本类中使用和调用
private String name;
private int age;
private String sex;
//在类中提供一些可以操作这些属性的方法
//get()方法获得这个数据
public void setName(String name) {
this.name = name;
}
//set()方法给这个数据设置值
public String getName() {
return name;
}
}
package oop;
import oop.demo02.Demo01;
//创建一个包含main方法的类,通过类Demo01中的方法来操作类中的属性
public class Application {
public static void main(String[] args) {
//new一个对象
Demo01 demo01 = new Demo01();
//调用setName()方法,给这个数据设置值
demo01.setName("Java");
//调用getName()方法,获得这个数据
System.out.println(demo01.getName());
}
}
- 通过Alt+Insert快捷键可以快速创建一些方法:如get()和set()
- 通过封装的思想,可以在方法中设置一些条件,防止对属性操作的不合法性
package oop.demo02;
public class Demo01 {
private String name;
private int age;
private String sex;
public int getAge() {
return age;
}
public void setAge(int age) {
//判断输入数据是否合法
if (age>120&&age<0){
this.age=-1;
}else {
this.age = age;
}
}
}
package oop;
import oop.demo02.Demo01;
public class Application {
public static void main(String[] args) {
Demo01 demo01 = new Demo01();
demo01.setAge(130);//数据不合法,输出结果为-1
System.out.println(demo01.getAge());
}
}
- 封装的意义
- 提高程序的安全性,保护数据
- 隐藏代码的实现细节
- 同一接口
- 提高系统的可维护性
继承
- 继承的本质是对某一些类的抽象,继承是类和类之间的一种关系
- 继承关键词:extends,意思为“扩展”,继承关系的两个类,一个是子类(派生类);一个是父类(基类);子类继承父类,子类是父类的扩展,
- Java中类只有单继承,没有多继承
- 子类和父类,从意义上讲应该具有“is a”的关系
package oop.demo02;
//创建一个父类Teenagers
public class Teenagers {
//属性age是public修饰,可以被其他类调用
public int age=18;
//创建一个方法
public void learn(){
System.out.println("青年要好好学习");
}
}
package oop.demo02;
//子类,继承于类Teenagers
//则子类Student就拥有了父类的全部方法
public class Student extends Teenagers {
}
package oop;
import oop.demo02.Student;
//检验子类是否具有了父类的方法
public class Application {
public static void main(String[] args) {
//创建一个Student对象
Student student = new Student();
System.out.println(student.age);//输出:18
student.learn();//输出:青年要好好学习
}
}
- super关键字
package oop.demo02;
public class Teenagers {
protected String name = "篮球";
}
package oop.demo02;
public class Student extends Teenagers {
private String name="足球";
public void test(String name){
System.out.println(name);
System.out.println(this.name);
System.out.println(super.name);
}
}
package oop;
import oop.demo02.Student;
public class Application {
public static void main(String[] args) {
Student student = new Student();
student.test("爬山");
}
}
//通过运行,输出结果:
//1.爬山
//2.足球
//3.篮球
-
super总结
- super调用的是父类的构造方法,且必须放在子类构造方法的第一个
- super只能出现在子类的方法或者构造方法中
- super和this不能同时调用构造方法
-
this总结
-
this代表的是本身调用者这个对象,而super代表的是父类对象的引用
-
this在没有继承的条件下都可以使用,super只能在继承条件下使用
-
this的构造方法时本类的构造,super的构造方法时父类的构造
-
-
重写方法
ackage oop.demo02;
public class Teenagers {
//父类的方法
public void test(){
System.out.println("篮球");
}
}
package oop.demo02;
public class Student extends Teenagers {
@Override //注解,有功能的注释
//重写父类的方法,重写都是对方法的重写,与属性无关
public void test() {
System.out.println("足球");
}
public void test1(){
test();
this.test();
super.test();
}
}
package oop;
import oop.demo02.Student;
public class Application {
public static void main(String[] args) {
Student student = new Student();
student.test1();
}
}
//通过运行,输出结果:
//1.足球
//2.足球
//3.篮球
-
静态方法和非静态方法的重写调用情况不一样
-
静态方法的调用
package oop.demo02; public class B { public static void test(){ System.out.println("B001"); } }
package oop.demo02; public class A extends B { public static void test(){ System.out.println("A001"); } }
package oop; import oop.demo02.A; import oop.demo02.B; public class Application { public static void main(String[] args) { //方法的调用只和左边定义的数据类型有关 A a = new A(); a.test();//输出结果:A001 //父类的引用指向了子类 B b=new A(); b.test();//输出结果:B001 } }
-
非静态方法的调用
package oop.demo02; public class B { public void test(){ System.out.println("B001"); } }
package oop.demo02; public class A extends B { public void test(){ System.out.println("A001"); } }
package oop; import oop.demo02.A; import oop.demo02.B; public class Application { public static void main(String[] args) { A a = new A(); a.test();//输出结果:A001 B b=new A();//子类重写了父类的方法 b.test();//输出结果:A001 } }
-
多态
- 即同一个方法可以根据发送对象的不同而采用多种不同的行为方式
- 一个对象的实际类型是确定的(如new Student),但是可以指向对象的引用类型有很多(如父类,有关系的类(如Object类))
- 多态存在的条件
- 有继承关系
- 子类重写父类方法
- 父类引用指向子类对象
package oop.demo02;
public class Teenagers {
public void test(){
System.out.println("篮球");
}
}
package oop.demo02;
public class Student extends Teenagers {
@Override
public void test() {
System.out.println("足球");
}
public void test1(){
System.out.println("吃早餐很重要");
}
}
package oop;
import oop.demo02.Student;
import oop.demo02.Teenagers;
public class Application {
public static void main(String[] args) {
//子类可以调用自身或者父类的方法
Student a=new Student();
a.test();//运行结果为:足球
//父类可以指向子类,但是不能调用子类独有的方法
Teenagers b=new Student();
b.test();//子类重写了父类的方法,执行的是子类的方法,运行结果为:足球
b.test1();//保错,父类不能直接调用子类独有的方法,需要转换类型后调用
((Student)b).test1();//转换类型后调用,运行结果:吃早餐很重要
}
}
- 多态是方法的多态,属性没有多态
- 父类和子类必须有关联
- 存在条件:有继承关系时,方法需要重写,父类引用指向了子类对象
- 不能重写方法的情况:
- static方法,属于类本身,不属于实例
- final 常量
- private方法,私有的
- 不能重写方法的情况: