JAVA面向对象

super和this

super关键字:我们可以通过super关键字来实现对父类成员的访问,用来引用当前对象的父类。
this关键字:指向自己的引用。

子类继承父类的注意事项

子类是不继承父类的构造器(构造方法或者构造函数)的,它只是调用(隐式或显式)。如果父类的构造器带有参数,则必须在子类的构造器中显式地通过 super 关键字调用父类的构造器并配以适当的参数列表。
如果父类构造器没有参数,则在子类的构造器中不需要使用 super 关键字调用父类构造器,系统会自动调用父类的无参构造器。

子类继承父类后代码是如何执行的

下面一段代码将说明

public class Homework6 {
    public static void main(String[] args) {
        new H2();
    }
}
class H1{
    {
        System.out.println("父类代码块");
    }
    public H1(){
        System.out.println("父类构造");
    }
    static{
        System.out.println("父类静态代码块");
    }
}
class H2 extends H1{
    static{
        System.out.println("子类静态代码块");
    }
    {
        System.out.println("子类代码块");
    }
    public H2(){
        System.out.println("子类构造");
    }
}

执行结果

父类静态代码块
子类静态代码块
父类代码块
父类构造
子类代码块
子类构造

说明
首先明白一个问题
代码块是在每次调用构造方法的时候执行,每调用一次执行一次,并且优先于构造方法执行
1.java程序中静态内容是随着类的加载而加载的,由于存在继承关系,因此先加载父类而后加载子类,相应的就是先执行父类静态代码块,再执行子类静态代码块。
2.类加载完成后程序就开始执行main方法中,紧接着进行初始化工作,由于代码块执行优于构造方法,因此出现先执行父类代码块,再执行父类构造方法,紧接着子类代码块,子类构造方法。
3.类的初始化是分层初始化的,先对父类进行初始化,再对子类进行初始化。在目标类中执行顺序为:1.成员变量初始化:默认初始化----》显示初始化----》构造方法初始化。

在继承中调用不得不说到多态的问题

使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,再去调用子类的同名方法。
多态的好处:可以使程序有良好的扩展,并可以对所有类的对象进行通用处理。
实例代码

/**
 * 多态的演示(好处)
 */
public class Polymorphic {
    public static void main(String[] args) {
       show(new Cat());
        show(new Dog());
        Animal animal = new Cat();//向上转型
        animal.eat();//调用Cat的方法
        Cat cat = (Cat)animal;//向下转型
        cat.work();//调用Cat中的work
    }

    public static void show(Animal animal){
        animal.eat();
        if (animal instanceof Cat){
            Cat cat =(Cat)animal;//猫做的事情
            cat.work();
        }
        if(animal instanceof Dog){
            Dog dog =(Dog)animal;//狗做的事情
            dog.eat();
        }
    };
    abstract static class Animal {
        abstract void eat();
    }

    static class Cat extends Animal {
        public void eat() {
            System.out.println("吃鱼");
        }
        public void work() {
            System.out.println("抓老鼠");
        }
    }
    static class Dog extends Animal {
        public void eat() {
            System.out.println("吃骨头");
        }
        public void work() {
            System.out.println("看家");
        }
    }
}

多态的实现方式

方式一:重写:

(1)方法重载是一个类中定义了多个方法名相同,而他们的参数的数量不同或数量相同而类型和次序不同,则称为方法的重载(Overloading)。
(2)方法重写是在子类存在方法与父类的方法的名字相同,而且参数的个数与类型一样,返回值也一样的方法,就称为重写(Overriding)。
(3)方法重载是一个类的多态性表现,而方法重写是子类与父类的一种多态性表现。

方式二:接口

1.接口可以多继承(继承的都是接口)

2.接口的方法声明必须是 public abstract 即便不写默认也是

3.接口里面不能包含方法具体实现

4.类实继承接口必须实现接口里申明的全部方法,除非该类是抽象类

5.类里面可以声明 public static final 修饰的变量

6.接口不能被实例化,但是可以被实现类创建

接口的含义理解

接口可以理解成统一的协议, 而接口中的属性也属于协议中的内容。但是接口的属性都是公共的,静态的,最终的。

接口的成员特点:

1、成员变量只能是常量,默认修饰符 public static final
2、成员方法只能是抽象方法。默认修饰符 public abstract
所以,Java 接口中,使用变量的时候,变量必须被赋值。

//所以接口定义属性
public interface People {
    int age=10;
 // 接口里面定义的成员变量都是  public static final 修饰
    String name="输出名字";
    public void eat();  
}

什么时候使用抽象类和接口

如果你拥有一些方法并且想让它们中的一些有默认实现,那么使用抽象类吧。
如果你想实现多重继承,那么你必须使用接口。由于Java不支持多继承,子类不能够继承多个类,但可以实现多个接口。因此你就可以使用接口来解决它。
如果基本功能在不断改变,那么就需要使用抽象类。如果不断改变基本功能并且使用接口,那么就需要改变所有实现了该接口的类。

方式三:抽象类和抽象方法

抽象类除了不能实例化对象之外,类的其它功能依然存在,成员变量、成员方法和构造方法的访问方式和普通类一样。

由于抽象类不能实例化对象,所以抽象类必须被继承,才能被使用。也是因为这个原因,通常在设计阶段决定要不要设计抽象类。

父类包含了子类集合的常见的方法,但是由于父类本身是抽象的,所以不能使用这些方法。

在Java中抽象类表示的是一种继承关系,一个类只能继承一个抽象类,而一个类却可以实现多个接口

public abstract class Employee
{
   private String name;
   private String address;
   private int number;
   public Employee(String name, String address, int number)
   {
      System.out.println("Constructing an Employee");
      this.name = name;
      this.address = address;
      this.number = number;
   }
   public double computePay()
   {
     System.out.println("Inside Employee computePay");
     return 0.0;
   }
   public void mailCheck()
   {
      System.out.println("Mailing a check to " + this.name
       + " " + this.address);
   }
   public String toString()
   {
      return name + " " + address + " " + number;
   }
   public String getName()
   {
      return name;
   }
   public String getAddress()
   {
      return address;
   }
   public void setAddress(String newAddress)
   {
      address = newAddress;
   }
   public int getNumber()
   {
     return number;
   }
}

抽象方法

如果你想设计这样一个类,该类包含一个特别的成员方法,该方法的具体实现由它的子类确定,那么你可以在父类中声明该方法为抽象方法。

Abstract关键字同样可以用来声明抽象方法,抽象方法只包含一个方法名,而没有方法体。

抽象方法没有定义,方法名后面直接跟一个分号,而不是花括号。

声明抽象方法的注意事项

  1. 抽象类不能被实例化(初学者很容易犯的错),如果被实例化,就会报错,编译无法通过。只有抽象类的非抽象子类可以创建对象。

  2. 抽象类中不一定包含抽象方法,但是有抽象方法的类必定是抽象类。

  3. 抽象类中的抽象方法只是声明,不包含方法体,就是不给出方法的具体实现也就是方法的具体功能。

  4. 构造方法,类方法(用static修饰的方法)不能声明为抽象方法。

  5. 抽象类的子类必须给出抽象类中的抽象方法的具体实现,除非该子类也是抽象类

你可能感兴趣的:(JAVA面向对象)