1.继承
class 子类名 extends 父类名 {
}
除了static修饰的方法或者成员变量,其他都被继承
如下示例
class Animal{
public int age;
public String name;
public String color;
public void SetAndShow(String name,int age,String color){
this.name=name;
this.age=age;
this.color=color;
System.out.println(this.name+" "+this.color+" "+this.age);
}
}
//Dog类通过关键字extends 继承父类Animal
class Dog extends Animal{
public void bark(){
System.out.println(this.name+"汪汪叫");
}
}
//Cat通过extends继承到了Animal的成员
class Cat extends Animal{
public void bark(){
System.out.println(this.name+"喵喵叫");
}
}
public class Main {
public static void main(String[] args) {
Dog dog1=new Dog();
Cat cat1=new Cat();
dog1.SetAndShow("小黑",2,"黑色");
dog1.bark();
cat1.SetAndShow("咪咪",3,"狸花猫");
cat1.bark();
}
}
共性的抽取,对代码进行复用 ,当子类里面有与父类重名的成员时,子类优先,若任然想使用父类的该成员,则用 super 对成员名进行修饰(super . 成员名)
1.1子类中要如何调用父类的构造方法?
在子类的构造函数中用 super() 调用父类的构造方法,初始化父类的成员
//父类
class Animal{
public Animal(String color ,int age){//父类构造
this.age = age;
this.color = color;
}
public int age;
public String color;
public void SetAndShow(int age,String color){
this.age=age;
this.color=color;
System.out.println(this.color+" "+this.age);
}
}
class Dog extends Animal{ //子类
public String name;
public Dog(String name,int age,String color){
super(color,age);//调用父类构造方法
this.name=name;
}
public void bark(){
System.out.println(this.name+"汪汪叫");
}
}
public class Main {
public static void main(String[] args) {
Dog dog1=new Dog("xr",3,"hei");//创建对象
dog1.SetAndShow(2,"hei");
dog1.bark();
}
}
注意:
1.若父类显式定义无参或者默认的构造方法,在子类构造方法第一行默认有隐含的super(),即调用基类构造方法
2.如果父类构造方法是带有参数的,此时需要用户为子类显式定义构造方法,并在子类构造方法中选择合适的父类构造方法调用,否则编译失败
3.在子类构造方法中,super()调用父类构造时,必须是子类构造函数中第一条语句
4.this和super都是Java的关键字,都只能访问在类的非静态成员方法和字段,
5.this与super都应放在构造方法的的一条语句,且不能同时存在
1.1.1初始化顺序
1.静态代码块在最前,父类在子类前面(父静子静,父实例父构造,子实例子构造)
2.父类的实例与构造代码块
3.子类的实例与构造代码块
4.静态的只执行一次
1.2继承方式
1.2.1 final关键字
变量被final修饰就相当于常量,其值不可以被修改
类被final修饰,该类不可以被继承
方法被final修饰,方法不可以被修改
1.2.2组合
和继承类似,组合也是一种表达类之间关系的方式,也是能够达到代码重用的效果。组合并没有涉及到特殊的语法(诸如extends 这样的关键字),仅仅是将一个类的实例作为另外一个类的字段。
继承表示对象之间是is-a的关系,比如:狗是动物,猫是动物
组合表示对象之间是has-a的关系,比如:汽车与发动机,轮胎等之间的关系
2.多态
同一个引用调用同一个方法,但是由于引用的对象不同时,所表现出来的行为就不一样,我们把这种思想称之为多态
既然要发生多态,那肯定就有向上转型与重写
2.1向上转型
2.1.1父类引用,引用子类对象
在子类中, 写一个
1)与父类成员方法同名的方法,
2)形参个数,类型,顺序相同
3)返回值相同可以不同,但是必须具有父子关系的方法,通过父类引用 去调用该同名方法 此时,调用的是 子类的方法,这个过程,就叫做动态绑定,(编译期间无法确定该引用调用的方法是父类的还是子类的方法,而静态绑定,是在编译期间就已经确定要调用的方法了,如方法的重载)
注意:父类的构造方法中调用 父类与子类同名的方法的时候 此时也会发生动态绑定(此时仍调用的是子类的方法)
2.1.2通过传参,实参与形参结合时
2.1.3返回值
2.2向下转型
子类引用 ,引用父类对象时
2.3重写
当子类要对父类以有的方法进行修改,那么就要在子类中进行方法的重写,保证以下几点
1.方法名相同
2.参数列表相同(个数顺序类型)
3.返回类型相同或者构成父子关系
这样,子类在实例化对象时,该对象要调用的方法就是被重写的方法了
注意:
1.被final修饰的密封方法不能被重写
2.被static修饰的方法不能被重写
3.子类的方法访问修饰限定符>=父类(父类被private修饰,不能被重写)
例如下面代码就是多态的运用
import demo1.Shape;
import demo1.Cycle;
class Rect extends Shape{
public void draw(){
System.out.println("画矩形");
}
}
class Third extends Shape{
public void draw(){
System.out.println("画三角形");
}
}
class Flower extends Shape{
public void draw(){
System.out.println("画❀");
}
}
public class Main {
public static void main(String[] args) {
Shape cycle= new Cycle();
//shape1.draw();
Shape rect=new Rect();
// shape2.draw();
Shape third=new Third();
// shape3.draw();
Shape flower=new Flower();
Shape [] shapes={flower,cycle,rect,cycle,third};
for (Shape shape:shapes){
shape.draw();
}
}
}