面向对象三大特性
封装
什么是封装
封装 是将代码及其处理的数据绑定在一起的一种编程机制,该机制保证了程序和数据都不受外部干扰且不被误用。
封装的作用
访问控制符
方法传参-值传递
传参类型是基本类型
程序案例:
public static void main(String[] args) {
int a = 3;
/*
* a 是一个基本数据类型
*/
func(a);
System.out.println("a=" + a);
}
public static void func(int a) {
a = a + 5;
}
程序运行结果:
a=3
传参类型是引用类型
程序案例(一):
public static void main(String[] args) {
Car car = new Car();
car.setColor("黑色");
func(car);
System.out.println("car的颜色: " + car.getColor());
}
public static void func(Car car) {
car.setColor("红色");
}
程序运行结果:
car的颜色: 红色
程序案例(二):
public static void main(String[] args) {
Car car = new Car();
car.setColor("黑色");
func(car);
System.out.println("car的颜色: " + car.getColor());
}
public static void func(Car car) {
car = new Car();
car.setColor("绿色");
}
程序运行结果:
car的颜色: 黑色
参数是引用类型的分析:
① 实参调用func(car)的没有传入引用car,而是car的值。
② 可以认为调用的时候是另外一个引用carx,此引用carx也引用此对象。
③ 在方法func()中的操作,是针对carx的,原来的car引用依然引用原对象。
继承
为什么使用继承
代码存在的问题: 代码重复。
java的继承特点
继承语法
class A extends B{
}
A c = new B();
B产生的对象是A类型,一般我们认为 c IS A A的形式.
c instaneof A : instance 关键字用来测试 c 是否是A产生的对象实例。
super关键字
父类对象的引用,super.name表示 父类的name属性,**super()**表示父类的无参构造方法。
方法覆盖(重写)
程序案例:
public class Transportation {
public void run() {
System.out.println("交通工具能跑起来...");
}
}
class Ship extends Transportation{
@Override
public void run() {
System.out.println("轮船在水中运行...");
}
}
方法覆盖:
- 有继承关系
- 子类与父类的方法名、参数类型、个数完全一致
抽象类
什么是抽象类?
在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。
抽象类定义
public abstract class 类名{
}
抽象类特性
-
不能实例化,只是提供为子类继承。
-
其它特性和普通类(非抽象类)相同。
抽象类应用场景
定义基本的属性、方法,子类去完成抽象的方法。抽象类可以完成部分通用工作,抽象放大发规范了子类的对外的方法,由子类具体完成。
程序案例:
接口
什么是接口?
java单继承的特性使java的子类不能同时具体继承多个类的方法。java设计者设计了接口的概念从形式上实现了多继承的能力,但是继承的方法都是抽象的,父类并没有具体实现,是一种虚拟的多继承能力,这种特殊的形式命名为接口。我们也可以把它看作一个彻底的抽象类,即所有方法都是抽象的。
接口语法
/**
* 定义接口
*/
public interface A{
}
/**
* 定义接口的实现(可以看作抽象类的子类)
*/
public class B implements A{
}
程序案例:
public interface IRun {
int SIZE = 3;
void run();
}
接口的特性
1.数据都是常量,例如:public static final int SIZE= 1;
2.方法都是抽象的,例如:public static abstract void f();
注意:jdk1.8+,允许接口的方法中使用具体实现,不过要在方法前加****default****关键字。
default void run() {
System.out.println("测试接口的default关键字");
}
3.接口可以继承多个接口
interface A extends B, C{}
4.接口中没有构造方法(数据都是常量)
5.接口不能实例化,实例化方法:
接口类型 引用名称= new 接口实现类();
例如: A a = new B();
接口和抽象类的区别
instanceof 关键字
instanceof 关键字使用用来检查某一个对象是否是一个类的实例。
例如: a instanceof A ; //a 是否是A类型的实例
向上、下转型
假设定义动物类(Animal)为父类,Bird为Animal的子类。那么定义方式如下:
Animal a = new Bird();
向上转型
左边的类型Bird是由Animal派生出来的,a引用定义为Animal类型。即Bird类型转换为Animal,是向上转型,注意此种方式定义后,我们只能在a中看到Animal中定义的方法,Bird中扩展的方法是不可见。
向下转型
如果要使用Bird的方法呢?Bird b = (Bird) a; 类似于我们基本类型的强转,将Animal类型向下转型为Bird类型
多态
什么是多态
多态是指引用变量在编译期间是不确定的,只有运行期才能确定,这样不用修改源码就可以把变量绑定到不同的类实例上,让程序拥有了多个运行状态。
多态的作用
应用程序不必为每一个派生类(子类)编写功能调用,只需要对抽象基类进行处理即可。大大提高程序的可复用性。派生类(子类/接口的实现类)的功能可以被父类的方法或引用变量所调用,这叫向后兼容,可以提高可扩充性和可维护性。
程序案例:
定义方法: public void drive(IMove im){
im.move( );
}
多态使用: IMove im = new Ship();
drive(im);
实现多态的必要条件
- 存在继承/接口实现关系
- 父类的引用指向子类对象(即类型相同)
- 子类对父类方法覆盖(重写)