理解继承 组合 多态
Posted 3 ERROR(s)
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了理解继承 组合 多态相关的知识,希望对你有一定的参考价值。
前言
代码中创建的类朱总要是抽象现实中的一些事物,有的时候客观事物之间就存在一些关联关系,那么表示成类和对象的时候也会存在一定的关联,例如有一个动物类,有一个猫类和一个狗类,这三个类存在了一定的联系,猫和狗都属于动物,他们都可以继承动物当中的一些属性从而达到代码重用的效果。
一、继承
1.继承使用背景
Animal类
public class Animal
public String name;
public Animal(String name)
this.name=name;
public void eat(String food)
System.out.println(this.name+"正在吃"+food);
猫类
public class Cat
public String name;
public Cat(String name)
this.name=name;
public void eat(String food)
System.out.println(this.name+"正在吃"+food);
狗类
public class Dog
public String name;
public Dog(String name)
this.name=name;
public void eat(String food)
System.out.println(this.name+"正在吃"+food);
public void run()
System.out.println(this.name+"i m running");
测试类
public class Test
public static void main(String[] args)
Animal animal=new Animal("动物");
animal.eat("beef");
Cat cat=new Cat("小猫");
cat.eat("猫粮");
Dog dog=new Dog("小狗");
dog.eat("狗粮");
dog.run();
结果:
- 我们发现上面三个类都具备一个相同的eat方法,而且行为完全一致。
- 并且他们都具备一个name属性。
- 从逻辑上来说cat和dog都是animal的一种(is a 关系)
所以我们就可以让cat和dog继承animal类来达到代码的重用。
2.继承语法规则
class 子类 extends 父类
- java中一个子类只能继承一个父类。
- 子类会继承父类所有public的字段和方法
- 对于父类的private的字段和方法,子类无法访问(但是继承了)
- 可以使用super得到父类实例的引用。
使用继承之后新的Cat类
public class Cat extends Animal
public Cat(String name)
super(name);
使用继承之后新的Dog类
public class Dog extends Animal
public Dog(String name)
super(name);
public void run()
System.out.println(this.name+"i m running");
3.protected关键字
当我们把父类中的字段改为private修饰之后会出现已下结果
因为private修饰的变量只能在类内被访问。
但是如果我们把访问修饰符改为public又违背了我们的初衷。
这时候protectde关键字的作用便发挥了出来。
+ private:类内部访问,类外部不能访问。
+ default:类内部能访问,用一个保重的类可以访问,其他类不能访问。
+ protected:类内部能访问,子类和同一个包中的类可以访问,其他类不可以访问。
+ public:类内部和类的调用者都可以访问
4.final关键字
我们的继承可以实现多层继承,但是实际的开发中我们一般不希望出现三层以上的继承关系,如果继承层次太多,就要考虑代码重构了。
当我们不想让一个类被继承的时候就要用到final关键字了。
final public class Animal
public String name;
public Animal(String name)
this.name=name;
public void eat(String food)
System.out.println(this.name+"正在吃"+food);
我们可以发现当使用final修饰Animal类之后,Cat继承Animal会报错
final的三种用法:
- final修饰变量:表示该变量不可被修改。
- final修饰方法:表示该方法不能被重写。
- final修饰类:表示该类不能被继承。
二、组合
和继承类似。组合也是一种表达类之间关系的方式,也能达到代码重用的效果。
组合表示has a语义
老师类
public class Teacher
int age ;
String name;
学生类
public class Student
int age;
String name;
他们都属于学校
public class School
public Student [] students;
public Teacher [] teachars;
三、多态
1.什么是多态?
- 父类引用子类对象
- 父类和子类有同名的覆盖方法
- 通过父类引用代用子类这个重写的方法的时候发生运行时绑定,也可以称之为多态。
public class shape 父类
public void draw()
class Cycle extends shape 子类继承父类
@Override
public void draw() 重写方法
System.out.println("画了一个大圆圈");
class Rect extends shape
@Override
public void draw()
System.out.println("画了一个正方形");
class Six extends shape
@Override
public void draw()
System.out.println("画了一个666");
2.向上转型
刚才我们有这样一行代码
Cat cat=new Cat("猫粮");
我们可以将它改写为以下形式
public class Test
public static void main(String[] args)
Cat cat=new Cat("小猫");
Animal cat2=cat;
animal.eat("猫粮");
或者这种形式
Animal cat2=new Cat("小猫");
此处的 cat2 是父类 Animal 的引用,他指向了子类 Cat 的实例 cat,这种现象我们称为向上转型。
向上转型发生的时机
- 直接赋值
- 作为参数传递
- 作为方法的返回值传递。
3.动态绑定
定义:父类引用引用子类对象,同时父类引用调用同名的覆盖方法。
父类
public class Animal
public String name;
public Animal(String name)
this.name=name;
public void eat(String food)
System.out.println("这是父类的eat方法");
System.out.println(this.name+"正在吃"+food);
子类
public class Cat extends Animal
public Cat(String name)
super(name);
public void eat(String food)
System.out.println("这是子类的eat方法");
System.out.println(this.name+"正在吃"+food);
测试类
public class Test
public static void main(String[] args)
Animal animal = new Animal("小猫");
Animal animal2=new Cat("小猫");
animal.eat("饭饭");
animal2.eat("饭饭");
- animal ,animal2都是 Animal 类型的引用,但是animal 指向的是Animal 类型的实例,
- animal2 指向的是 Cat类型的实例。
- animal 调用了父类的 eat 方法,animal2 调用了子类的eat方法。
在调用javap -c之后我们看到在编译的时候animal调用的确实是父类的 eat( )方法,但是在运行的时候他却调用了子类的 eat( )方法,所以我们称他为运行时多态或动态绑定。
4.方法重写
例如刚才的子类eat方法,
子类实现父类的同名方法,并且参数列表完全一样的时候,这种情况称为方法重写。
方法重写的注意事项:
- 普通方法可以被重写,但是static修饰的方法不能被重写。
- 子类方法的访问权限不能低于父类的访问权限。
- 重写方法用@Override注解来标注。
方法重载和方法重写的区别:
以上是关于理解继承 组合 多态的主要内容,如果未能解决你的问题,请参考以下文章