继承
class Animal{
private String name;
public Animal(String name) {
this.name = name;
}
public void eat(String food){
System.out.println(name + " 正在吃 " + food);
}
}
class Cat extends Animal{
//Cat也包含name,是private类型
public Cat(String name) {
// ! this.name = name;
//name有继承过来,但是是private修饰的,不能直接访问,需要调用基类构造器方法
super(name);
}
}
继承:目的为了代码重用,把公共的代码,放到一个单独的类之中,让其他的类,继承这个单独的类,单独的这个类里面包含的属性和方法,都自动被被新类支持进去。
并且,新的类还可以做出一些根据自己特色的扩展
Animal : 父类/基类/超类
Cat: 子类/派生类
父类和子类的关系,称为“is-a”
语法规则:
- 对于父类的private的字段和方法,子类中是无法访问的。
- Java中一个子类只能继承一个父类
- 子类的实例中,也包含着父类的实例,可以用super关键字得到父类实例的引用。
gettname()也可以用protected方法替代,protected:不同包的子类中也能使用!
package package1;
import package2.Animal;
//Animal类中的name用protected修饰
public class Bird extends Animal {
public Bird(String name) {
super(name);
}
public void fly(){
System.out.println( name + " 正在飞 ");
}
}
访问控制权限使用的原则:
尽可能的进行封装
private default pritected public
字段设为private,方法需要具体考虑,该设成public就设成public,有时候也设成private
final
final 修饰一个变量,表示这是一个常量
final 修饰一个类,表示这个类是不能被继续继承的。
final public class ChineseGardenCat extends Cat
//其他的类就不能继承 ChineseGardenCat
组合
has - a 关系
public class School {
private Teacher teacher ;
private Student[] students;
}
根据语义选择组合或者继承“has - a ” 和“is - a ”
多态
向上转型:类型转换,类和类之间的关系(父类和子类)
public class Test1 {
public static void main(String[] args) {
Bird bird = new Bird("圆圆");
Animal animal = bird;//直接赋值
}
}
两个不同的类型相互赋值
一个子类的对象,可以使用一个父类的引用去表示
public class Test1 {
public static void main(String[] args) {
Bird bird = new Bird("圆圆");
Animal animal = bird;//直接赋值
bird.eat("谷子");
animal.eat("小米");
}
}
bird 和animal 都指向 Bird对象,都是鸟在吃
向上转型的三种常见体现形式。
- 直接赋值
- 作为方法的参数
- 作为方法的返回值
public static void main(String[] args) {
Bird bird = new Bird("圆圆");//实参
feed(bird);
Animal animal = findMyAnimal();
}
public static void feed(Animal animal){
//animal是形参,实际引用的是Bird类型对象
animal.eat("谷子");
}
public static Animal findMyAnimal(){
Bird bird = new Bird("圆圆");
return bird;
}
动态绑定
父类和子类可能会包含名字相同,逻辑不同的方法。
调用这个方法的时候,到底执行的是 父类的方法 还是 子类的方法,是在程序运行过程中确定的
动态指的是“运行时”而不是编译期
public class Test1 {
public static void main(String[] args) {
Animal animal = new Bird("圆圆");
animal.eat("谷子");
}
}
与后面的(new )有关
子类也有eat,父类也有eat,方法的覆写(名相同,逻辑不同)
- 方法名相同
- 参数必须完全相同(个数和类型)
- 返回值没有要求,一般让返回值一样
- 子类的方法访问权限控制不应该父类的小
多态:是一种思想方法,多态落实到代码上具体的体现形式,就是通过一下这三点来体现的。
- 向上转型
- 动态绑定
- 方法重写
package package4;
class Shape{
public void draw(){
//啥都不画
}
}
class Circle extends Shape{
@Override
public void draw() {
System.out.println("⚪");
}
}
class Rect extends Shape{
@Override
public void draw() {
System.out.println("□");
}
}
class Flower extends Shape{
@Override
public void draw() {
System.out.println("♣");
}
}
public class Test2 {
public static void main(String[] args) {
//向上转型
Shape s1 = new Circle();
Shape s2 = new Rect();
Shape s3 = new Flower();
drawShape(s1);
drawShape(s2);
drawShape(s3);
}
public static void drawShape(Shape s){
s.draw();
}
}
多态是一种代码编写的方式,一个引用可以表现出不同的形态,
Flower Rect Circle 这些类是“类的实现者”编写的
Test 这个类(drawShape 方法)“类的调用者”编写的。
类的调用者不必关心当前类是啥类(直接s.draw())
就让类的调用者对类的实现细节知道的更少了
封装的更进一步
前面说的封装,是为了让类的调用者不需要知道类的实现细节(还是得知道这个类是啥类)
多态这里的类的调用者都不需要知道这个类是啥类,只需要知道这个类有一个draw()方法就可以了