面向对象的简单理解:
- 面向对象是相对于面向过程的一种编程方式。 面向过程分析解决问题所需的步骤,然后直接写出实现方法。
面向对象是以对象为基本单位,你不需要知道怎么具体的去解决问题,你只要告诉对象你需要干什么。即对对象实例化。对象本身便会执行。
一个类中可以包含很多对象。类是对对象的抽象。对象是对类的一个实例。
面向对象的三大特性:
- 封装性、继承性、多态性
封装
- 把描述一个对象的属性和行为封装成一个类,把具体的业务逻辑功能实现封装成一个方法,其次封装的意义还有效的保护属性通过访问修饰符私有化属性(成员变量),公有化方法。
继承
- 实现代码的复用,所有的子类所共有的行为和属性抽取为一个父类,所有的子类继承该类可具备父类的属性和行为,继承具有单一性和传递性。
class 子类 extends 父类 {
}
- 使用 extends 指定父类。
- Java 中一个子类只能继承一个父类 (而C++/Python等语言支 持多继承)。
- 子类会继承父类的所有 public 的字段和方法。
- 对于父类的 private 的字段和方法, 子类中是无法访问的。
- 子类的实例中, 也包含着父类的实例. 可以使用 super 关键字得到父类实例的引用。(因为他继承父类的成员使用,使用前这些成员必须初始化,而他们是父类的成员,所以,必须通过父类进行初始化。所以,会先创建一个父类的对象。)
- 子类不能继承父类的构造方法。子类创建对象时,先会创建父类的对象。默认是调用父类的无参构造方法。
class Anmial {
public String name;
public Anmial(String name) {
this.name = name;
}
public void eat(String food) {
System.out.println(this.name + "正在吃" + food);
}
}
class Cats extends Anmial {
public Cats(String name) {
//使用super调用父类的构造方法。
super(name);
}
}
class Birds extends Anmial {
public Birds(String name) {
super(name);
}
public void fly() {
System.out.println(this.name + "正在飞 ︿( ̄︶ ̄)︿");
}
}
public class Test {
public static void main(String[] args) {
Cats cat = new Cats("小黑");
cat.eat("猫粮");
Birds bird = new Birds("圆圆");
bird.fly();
}
}
我们发现, 如果把字段设为 private,子类不能访问.。但是设成 public,,又违背了我们 “封装” 的初衷。
两全其美的办法就是 protected 关键字。
对于类的调用者来说, protected 修饰的字段和方法是不能访问的。
对于类的子类 和 同一个包的其他类 来说, protected 修饰的字段和方法是可以访问的。
关于super的三个用法:
派生类的构造函数中,调用super(10),调用带int参数的其它构造方法。
super.func() 派生类中调用基类的方法。
super.a 派生类继承的基类成员变量a。
关于this的两个用法:
在构造方法中调用this(10),调用带int参数的其它构造方法
成员方法中访问其它成员 前可以添加this
多态
- 程序中定义的引用类型变量所指向的具体类型和调用的具体方法在程序编译阶段无法确定,而是在运行期才能确定该引用类型变量指向具体哪个对象而调用在哪个类中声明的方法。
1.向上转型
向上转型发生的时机:
1.直接赋值
Birds bird = new Birds("圆圆");
//可以写成下面的样子
Bird bird = new Bird("圆圆");
Animal bird2 = bird;
// 或者写成下面的方式
Animal bird2 = new Bird("圆圆");
此时 bird2 是一个父类 (Animal) 的引用, 指向一个子类 (Bird) 的实例. 这种写法称为 向上转型.
2.方法传参
public class Test {
public static void main(String[] args) {
Birds bird = new Birds("圆圆");
feed(bird);
}
public static void feed(Animal animal) {
animal.eat("谷子");
}
}
3.方法返回
public class Test {
public static void main(String[] args) {
Animal animal = findMyAnimal();
}
public static Animal findMyAnimal() {
Bird bird = new Bird("圆圆");
return bird;
}
}
2.动态绑定:在 Java 中,调用某个类的方法,究竟执行了哪段代码 (是父类方法的代码还是子类方法的代码) ,要看究竟这个引用指向的是父类对象还是子类对象. 这个过程是程序运行时决定的(而不是编译期), 因此称为动态绑定。
3.向下转型
// (Bird) 表示强制类型转换
Animal animal = new Bird("圆圆");
Birds bird = (Birds)animal;
bird.fly();
// 执行结果
圆圆正在飞