Java超详细讲解继承和多态的使用

目录
  • 继承和多态
  • 1、继承
    • 1.1、继承概念
    • 1.2、继承的语法
    • 1.3、父类成员的访问
      • 1.31、子类和父类不存在同名成员变量
      • 1.32、子类和父类成员变量同名
      • 1.33、成员方法名字不同
      • 1.34、 成员方法名字相同
    • 1.4、super关键字
    • 1.5、子类构造方法
    • 1.6、super和this
    • 1.7、初始化
    • 1.8、protected关键字
    • 1.9、继承方式
    • 1.10、final关键字
  • 2、继承与组合
  • 3、多态
    • 3.1、多态概念
    • 3.2、多态实现条件
    • 3.3、重写
    • 3.4、向上转型和向下转型
    • 3.5、多态优缺点
    • 3.6、避免在构造方法中调用重写的方法

继承和多态

学习继承、组合、多态

1、继承

1.1、继承概念

专门用来进行共性抽取,实现代码复用。 它允许程序员在保持原有类特 性的基础上进行扩展,增加新功能,这样产生新的类,称派生类。

1.2、继承的语法

在Java中如果要表示类之间的继承关系,需要借助extends关键字

class Animal{
    public String name;
    public int age;
    public String sex;
    public void eat(){
        System.out.println(this.name+"cat::eat()!");
    }
    public void sleep(){
        System.out.println(this.name+"睡觉!");
    }
}
/**
 * 继承  其实就是对共性的抽取  从而达到了代码的复用
 */
class Cat extends Animal{
    public void mew(){
        System.out.println(this.name+"cat::mew()!");
    }
}
class Dog extends Animal{
    public void bark(){
        System.out.println("dog::bark()!");
    }
}
public class TestDemo {
    public static void main(String[] args) {
        Cat cat = new Cat();
        cat.name = "咪咪";
        cat.sleep();
        cat.eat();
        cat.mew();
    }
}

注意:

1. 子类会将父类中的成员变量或者成员方法继承到子类中了

2. 子类继承父类之后,尽量新添加自己特有的成员,体现出与基类的不同,否则就没有必要继承了

1.3、父类成员的访问

1.31、子类和父类不存在同名成员变量

public class Base {
    int a;
    int b;
}
public class Derived extends Base{
    int c;
    public void method(){
        a = 10;    // 访问从父类中继承下来的a
        b = 20;    // 访问从父类中继承下来的b
        c = 30;    // 访问子类自己的c
   }
}

1.32、子类和父类成员变量同名

class Base {
    public int a = 1;
    public int b = 2;
    public void method(){
        System.out.println("BASE::TEST()");
    }
}
class Derived extends Base{
    public int a = 3;
    public int d = 4;
    public void method2(){
        System.out.println("Derived::method2()");
    }
    public void test(){
        method2();
        method();
        /*System.out.println(a);//如果重名类  优先访问自己的
        System.out.println(super.a);//写代码的时候  让这个代码更已读
        System.out.println(this.b);
        System.out.println(d);*/
    }
}
public class TestDemo2 {
    public static void main(String[] args) {
        Derived derived = new Derived();
        derived.test();
    }
}

1、如果访问的成员变量子类中有,访问自己的成员变量。

2、如果访问的成员变量子类中无,则访问父类继承下来的,如果父类也没有定义,则编译报错。

3、如果访问的成员变量与父类中成员变量同名,则优先访问自己的,即:子类将父类同名成员隐藏了。

4、成员变量访问遵循就近原则,自己有优先自己的,如果没有则向父类中找。

比如:你和你父亲各自有一款相同的手机,平时使用时你肯定优先用自己的,如果自己手机没电了,你才会考虑使用父亲的。

1.33、成员方法名字不同

public class Base {
 public void methodA(){
     System.out.println("Base中的methodA()");
 }
}
public class Derived extends Base{
    public void methodB(){
        System.out.println("Derived中的methodB()方法");
   }
    public void methodC(){
        methodB();         // 访问子类自己的methodB()
        methodA();         // 访问父类继承的methodA()
        // methodD();     // 编译失败,在整个继承体系中没有发现方法methodD()
   }
}

总结:成员方法没有同名时,在子类方法中或者通过子类对象访问方法时,则优先访问自己的,自己没有时 再到父类中找,如果父类中也没有则报错。

1.34、 成员方法名字相同

public class Base {
 public void methodA(){
     System.out.println("Base中的methodA()");
 }
 public void methodB(){
     System.out.println("Base中的methodB()");
 }
}
public class Derived extends Base{
    public void methodA(int a) {
        System.out.println("Derived中的method(int)方法");
   }
    public void methodB(){
        System.out.println("Derived中的methodB()方法");
   }
    public void methodC(){
        methodA();      // 没有传参,访问父类中的methodA()
        methodA(20);    // 传递int参数,访问子类中的methodA(int)
        methodB();      // 直接访问,则永远访问到的都是子类中的methodB(),基类的无法访问到
   }
}

通过子类对象访问父类与子类中不同名方法时,优先在子类中找,找到则访问,否则在父类中找,找到 则访问,否则编译报错。 通过派生类对象访问父类与子类同名方法时,如果父类和子类同名方法的参数列表不同(重载),根据调用 方法适传递的参数选择合适的方法访问,如果没有则报错;如果父类和子类同名方法的原型一致,则只能访问到子类的,父类的无法通过派生类对象直接访问到。 问题:如果子类中存在与父类中相同的成员时,那如何在子类中访问父类相同名称的成员呢?

1.4、super关键字

public class Base {
    int a;
    int b;
 public void methodA(){
     System.out.println("Base中的methodA()");
 }
 public void methodB(){
 System.out.println("Base中的methodB()");
 }
}
public class Derived extends Base{
    int a;    // 与父类中成员变量同名且类型相同
    char b;   // 与父类中成员变量同名但类型不同
    // 与父类中methodA()构成重载
    public void methodA(int a) {
        System.out.println("Derived中的method()方法");
   }
    // 与基类中methodB()构成重写
    public void methodB(){
        System.out.println("Derived中的methodB()方法");
   }
    public void methodC(){
        // 对于同名的成员变量,直接访问时,访问的都是子类的
        a = 100;   // 等价于: this.a = 100;
        b = 101;   // 等价于: this.b = 101;
        // 注意:this是当前对象的引用
        // 访问父类的成员变量时,需要借助super关键字
        // super是获取到子类对象中从基类继承下来的部分
        super.a = 200;
        super.b = 201;
        // 父类和子类中构成重载的方法,直接可以通过参数列表区分清访问父类还是子类方法
        methodA();      // 没有传参,访问父类中的methodA()
        methodA(20);    // 传递int参数,访问子类中的methodA(int)
        // 如果在子类中要访问重写的基类方法,则需要借助super关键字
        methodB();      // 直接访问,则永远访问到的都是子类中的methodB(),基类的无法访问到
        super.methodB(); // 访问基类的methodB()
   }
}

【注意事项】

1. 只能在非静态方法中使用

2. 在子类方法中,访问父类的成员变量和方法。

1.5、子类构造方法

父子父子,先有父再有子,即:子类对象构造时,需要先调用基类构造方法,然后执行子类的构造方法。

public class Base {
public Base(){
        System.out.println("Base()");
 }
}
public class Derived extends Base{
   public Derived(){
       super();   // 注意子类构造方法中默认会调用基类的无参构造方法:super(),
       // 用户没有写时,编译器会自动添加,而且super()必须是子类构造方法中第一条语句,
       // 并且只能出现一次
       System.out.println("Derived()");
   }
}
public class Test {
    public static void main(String[] args) {
        Derived d = new Derived();
   }
}

结果打印:
Base()
Derived()

在子类构造方法中,并没有写任何关于基类构造的代码,但是在构造子类对象时,先执行基类的构造方法,然后执行子类的构造方法,因为:子类对象中成员是有两部分组成的,基类继承下来的以及子类新增加的部分 。父子父子 肯定是先有父再有子,所以在构造子类对象时候 ,先要调用基类的构造方法,将从基类继承下来的成员构造完整,然后再调用子类自己的构造方法,将子类自己新增加的成员初始化完整 。

注意:

1. 若父类显式定义无参或者默认的构造方法,在子类构造方法第一行默认有隐含的super()调用,即调用基类构

造方法

2. 如果父类构造方法是带有参数的,此时编译器不会再给子类生成默认的构造方法,此时需要用户为子类显式

定义构造方法,并在子类构造方法中选择合适的父类构造方法调用,否则编译失败。

3. 在子类构造方法中,super(…)调用父类构造时,必须是子类构造函数中第一条语句。

4. super(…)只能在子类构造方法中出现一次,并且不能和this同时出现

1.6、super和this

【相同点】

1. 都是Java中的关键字

2. 只能在类的非静态方法中使用,用来访问非静态成员方法和字段

3. 在构造方法中调用时,必须是构造方法中的第一条语句,并且不能同时存在

【不同点】

1. this是当前对象的引用,当前对象即调用实例方法的对象,super相当于是子类对象中从父类继承下来部分成员的引用

2. 在非静态成员方法中,this用来访问本类的方法和属性,super用来访问父类继承下来的方法和属性

3. this是非静态成员方法的一个隐藏参数,super不是隐藏的参数

4. 成员方法中直接访问本类成员时,编译之后会将this还原,即本类非静态成员都是通过this来访问的;在子类中如果通过super访问父类成员,编译之后在字节码层面super实际是不存在的

5. 在构造方法中:this(…)用于调用本类构造方法,super(…)用于调用父类构造方法,两种调用不能同时在构造方法中出现

6. 构造方法中一定会存在super(…)的调用,用户没有写编译器也会增加,但是this(…)用户不写则没有

1.7、初始化

class Person {
    public String name;
    public int age;
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
        System.out.println("构造方法执行");
   }
   {
        System.out.println("实例代码块执行");
   }
    static {
        System.out.println("静态代码块执行");
        }
}
public class TestDemo {
    public static void main(String[] args) {
        Person person1 = new Person("bit",10);
        System.out.println("============================");
        Person person2 = new Person("gaobo",20);
   }
}

执行结果:
静态代码块执行
实例代码块执行
构造方法执行
============================
实例代码块执行
构造方法执行

注意:

1. 静态代码块先执行,并且只执行一次,在类加载阶段执行

2. 当有对象创建时,才会执行实例代码块,实例代码块执行完成后,最后构造方法执行

继承关系上的执行顺序:

1、父类静态代码块优先于子类静态代码块执行,且是最早执行

2、父类实例代码块和父类构造方法紧接着执行

3、子类的实例代码块和子类构造方法紧接着再执行

4、第二次实例化子类对象时,父类和子类的静态代码块都将不会再执行

1.8、protected关键字

// 为了掩饰基类中不同访问权限在子类中的可见性,为了简单类B中就不设置成员方法了
// extend01包中
public class B {
    private int a;
    protected int b;
    public int c;
    int d;
}
// extend01包中
// 同一个包中的子类
public class D extends B{
    public void method(){
        // super.a = 10;     // 编译报错,父类private成员在相同包子类中不可见
        super.b = 20;         // 父类中protected成员在相同包子类中可以直接访问
        super.c = 30;         // 父类中public成员在相同包子类中可以直接访问
        super.d = 40;         // 父类中默认访问权限修饰的成员在相同包子类中可以直接访问
   }
}
// extend02包中
// 不同包中的子类
public class C extends B {
    public void method(){
        // super.a = 10;     // 编译报错,父类中private成员在不同包子类中不可见
        super.b = 20;        // 父类中protected修饰的成员在不同包子类中可以直接访问
        super.c = 30;        // 父类中public修饰的成员在不同包子类中可以直接访问
        //super.d = 40;     // 父类中默认访问权限修饰的成员在不同包子类中不能直接访问
   }
}
// extend02包中
// 不同包中的类
public class TestC {
    public static void main(String[] args) {
        C c = new C();
         c.method();
        // System.out.println(c.a);   // 编译报错,父类中private成员在不同包其他类中不可见
        // System.out.println(c.b);   // 父类中protected成员在不同包其他类中不能直接访问
        System.out.println(c.c);      // 父类中public成员在不同包其他类中可以直接访问
        // System.out.println(c.d);   // 父类中默认访问权限修饰的成员在不同包其他类中不能直接访问
   }
}

注意:父类中private成员变量随时在子类中不能直接访问,但是也继承到子类中了

1.9、继承方式

1.10、final关键字

final关键可以用来修饰变量、成员方法以及类。

1. 修饰变量或字段,表示常量(即不能修改)

2. 修饰类:表示此类不能被继承

2、继承与组合

组合表示对象之间的关系

// 轮胎类
class Tire{
    // ...
}
// 发动机类
class Engine{
    // ...
}
// 车载系统类
class VehicleSystem{
    // ...
}
class Car{
    private Tire tire;          // 可以复用轮胎中的属性和方法
    private Engine engine;      // 可以复用发动机中的属性和方法
    private VehicleSystem vs;   // 可以复用车载系统中的属性和方法
    // ...
}
// 奔驰是汽车
class Benz extend Car{
    // 将汽车中包含的:轮胎、发送机、车载系统全部继承下来
}

3、多态

3.1、多态概念

通俗来说,就是多种形态,具体点就是去完成某个行为,当不同的对象去完成时会产生出不同 的状态。

3.2、多态实现条件

1. 必须在继承体系下

2. 子类必须要对父类中方法进行重写

3. 通过父类的引用调用重写的方法

public class Animal {
String name;
    int age;
    public Animal(String name, int age){
        this.name = name;
        this.age = age;
   }
    public void eat(){
        System.out.println(name + "吃饭");
   }
}
public class Cat extends Animal{
    public Cat(String name, int age){
        super(name, age);
   }
    @Override
    public void eat(){
        System.out.println(name+"吃鱼~~~");
   }
}
public class Dog extends Animal {
    public Dog(String name, int age){
        super(name, age);
   }
    @Override
    public void eat(){
        System.out.println(name+"吃骨头~~~");
   }
}
///分割线//
public class TestAnimal {
    // 编译器在编译代码时,并不知道要调用Dog 还是 Cat 中eat的方法
    // 等程序运行起来后,形参a引用的具体对象确定后,才知道调用那个方法
    // 注意:此处的形参类型必须时父类类型才可以
    public static void eat(Animal a){
        a.eat();
   }
    public static void main(String[] args) {
        Cat cat = new Cat("元宝",2);
        Dog dog = new Dog("小七", 1);
        eat(cat);
        eat(dog);
   }
}

运行结果:
元宝吃鱼~~~
元宝正在睡觉
小七吃骨头~~~
小七正在睡觉

3.3、重写

重写(override):也称为覆盖。重写是子类对父类非静态、非private修饰,非final修饰,非构造方法等的实现过程进行重新编写, 返回值和形参都不能改变。即外壳不变,核心重写!重写的好处在于子类可以根据需要,定义特定于自己的行为。 也就是说子类能够根据需要实现父类的方法。

1. 子类在重写父类的方法时,一般必须与父类方法原型一致:修饰符 返回值类型 方法名(参数列表) 要完全一致

2. JDK7以后,被重写的方法返回值类型可以不同,但是必须是具有父子关系的

访问权限不能比父类中被重写的方法的访问权限更低。例如:如果父类方法被public修饰,则子类中重写该方法就不能声明为 protected

3. 父类被static、private修饰的方法、构造方法都不能被重写。

子类和父类在同一个包中,那么子类可以重写父类所有方法,除了声明为 private 和 final 的方法。

4. 子类和父类不在同一个包中,那么子类只能够重写父类的声明为 public 和 protected 的非 final 方法。

5. 重写的方法, 可以使用 @Override 注解来显式指定. 有了这个注解能帮我们进行一些合法性校验. 例如不小心将方法名字拼写错了 (比如写成 aet), 那么此时编译器就会发现父类中没有 aet 方法, 就会编译报错, 提示无法构成重写.

重载与重写区别:

方法重载是一个类的多态性表现,而方法重写是子类与父类的一种多态性表现。

3.4、向上转型和向下转型

向上转型:实际就是创建一个子类对象,将其当成父类对象来使用。

语法格式:父类类型 对象名 = new 子类类型()

【使用场景】

1. 直接赋值

2. 方法传参

3. 方法返回

public class TestAnimal {
    // 2. 方法传参:形参为父类型引用,可以接收任意子类的对象
    public static void eatFood(Animal a){
        a.eat();
   }
    // 3. 作返回值:返回任意子类对象
    public static Animal buyAnimal(String var){
        if("狗" == var){
            return new Dog("狗狗",1);
       }else if("猫" == var){
            return new Cat("猫猫", 1);
       }else{
            return null;
       }
   }
    public static void main(String[] args) {
        Animal cat = new Cat("元宝",2);   // 1. 直接赋值:子类对象赋值给父类对象
        Dog dog = new Dog("小七", 1);
        eatFood(cat);
        eatFood(dog);
        Animal animal = buyAnimal("狗");
        animal.eat();
        animal = buyAnimal("猫");
        animal.eat();
   }
}

将一个子类对象经过向上转型之后当成父类方法使用,再无法调用子类的方法,但有时候可能需要调用子类特有的

方法,此时:将父类引用再还原为子类对象即可,即向下转换。

public class TestAnimal {
    public static void main(String[] args) {
        Cat cat = new Cat("元宝",2);
        Dog dog = new Dog("小七", 1);
        // 向上转型
        Animal animal = cat;
        animal.eat();
        animal = dog;
        animal.eat();
        // 编译失败,编译时编译器将animal当成Animal对象处理
        // 而Animal类中没有bark方法,因此编译失败
        // animal.bark();
        // 向上转型
        // 程序可以通过编程,但运行时抛出异常---因为:animal实际指向的是狗
        // 现在要强制还原为猫,无法正常还原,运行时抛出:ClassCastException
        cat = (Cat)animal;
        cat.mew();
        // animal本来指向的就是狗,因此将animal还原为狗也是安全的
        dog = (Dog)animal;
        dog.bark();
   }
}

向下转型用的比较少,而且不安全,万一转换失败,运行时就会抛异常。Java中为了提高向下转型的安全性,引入

了 instanceof ,如果该表达式为true,则可以安全转换。

public class TestAnimal {
    public static void main(String[] args) {
        Cat cat = new Cat("元宝",2);
        Dog dog = new Dog("小七", 1);
        // 向上转型
        Animal animal = cat;
          animal.eat();
        animal = dog;
        animal.eat();
        if(animal instanceof Cat){
            cat = (Cat)animal;
            cat.mew();
       }
        if(animal instanceof Dog){
            dog = (Dog)animal;
            dog.bark();
       }
   }
}

3.5、多态优缺点

【使用多态的好处】

1. 能够降低代码的 “圈复杂度”, 避免使用大量的 if - else

就晓得了什么叫 “圈复杂度” ?那么我们来对比一下

这是if-else分支语句:

public static void drawShapes() {
    Rect rect = new Rect();
    Cycle cycle = new Cycle();
    Flower flower = new Flower();
    String[] shapes = {"cycle", "rect", "cycle", "rect", "flower"};

    for (String shape : shapes) {
        if (shape.equals("cycle")) {
            cycle.draw();
       } else if (shape.equals("rect")) {
            rect.draw();
       } else if (shape.equals("flower")) {
            flower.draw();
       }
   }
}

如果使用使用多态:

public static void drawShapes() {
    // 我们创建了一个 Shape 对象的数组.
    Shape[] shapes = {new Cycle(), new Rect(), new Cycle(),
                      new Rect(), new Flower()};
    for (Shape shape : shapes) {
        shape.draw();
   }
}

2. 可扩展能力更强

如果要新增一种新的形状, 使用多态的方式代码改动成本也比较低.

class Triangle extends Shape {
    @Override
    public void draw() {
        System.out.println("△");
   }
}

对于类的调用者来说(drawShapes方法), 只要创建一个新类的实例就可以了, 改动成本很低. 而对于不用多态的情况, 就要把drawShapes 中的 if - else 进行一定的修改, 改动成本更高.

多态缺陷:代码的运行效率降低。

3.6、避免在构造方法中调用重写的方法

我们创建两个类, B 是父类, D 是子类. D 中重写 func 方法. 并且在 B 的构造方法中调用 func

class B {
    public B() {
        // do nothing
        func();
   }
    public void func() {
        System.out.println("B.func()");
   }
}
class D extends B {
    private int num = 1;
    @Override
    public void func() {
        System.out.println("D.func() " + num);
   }
}
public class Test {
    public static void main(String[] args) {
        D d = new D();
        }
}

执行结果
D.func() 0

1. 构造 D 对象的同时, 会调用 B 的构造方法.

2. B 的构造方法中调用了 func 方法, 此时会触发动态绑定, 会调用到 D 中的 func此时 D 对象自身还没有构造, 此时 num 处在未初始化的状态, 值为 0.

结论: “用尽量简单的方式使对象进入可工作状态”, 尽量不要在构造器中调用方法(如果这个方法被子类重写, 就会触 发动态绑定,

但是此时子类对象还没构造完成), 可能会出现一些隐藏的但是又极难发现的问题.

到此这篇关于Java超详细讲解继承和多态的使用的文章就介绍到这了,更多相关Java继承和多态内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 新手小白入门必学JAVA面向对象之多态

    目录 1. 概念 2 . 特点 3. 练习:多态入门案例 4. 多态的好处 5. 多态的使用 6. 练习:多态成员使用测试 7 拓展 7.1 设计汽车综合案例 7.2 多态为了统一调用标准 7.3 静态变量和实例变量的区别 7.4 向上转型和向下转型 总结 1. 概念 多态是面向对象程序设计(OOP)的一个重要特征,指同一个实体同时具有多种形式,即同一个对象,在不同时刻,代表的对象不一样,指的是对象的多种形态. 可以把不同的子类对象都当作父类来看,进而屏蔽不同子类对象之间的差异,写出通用的代码,

  • Java超详细讲解多态的调用

    概念:多态是什么它就相当于区别对待,比如买票这个行为,当普通人买票时,是全价买票:学生买票时,是半价买票:军人买票时是优 先买票.再者就是再举个详细的例子: 最近为了争夺在线支付市场,支付宝年底经常会做诱人的扫红包-支付-给奖励金的活动.那么 大家想想为什么有人扫的红包又大又新鲜8块.10块…,而有人扫的红包都是1毛,5毛….其实这背后也是 一个多态行为.支付宝首先会分析你的账户数据,比如你是新用户.比如你没有经常支付宝支付等等,那么 你需要被鼓励使用支付宝,那么就你扫码金额 = random(

  • Java中接口的多态详解

    目录 多态参数 多态数组 接口的多态传递现象 总结 多态参数 就像我们现实生活中电脑的usb接口,我们既可以接受手机对象,又可以接受相机对象,等等,体现了接口的多态,查看以下代码 接口: package InterfaceM; public interface Interface { public void join(); public void stop(); } 手机类: package InterfaceM; public class Phone implements Interface{

  • Java十分钟精通多态与抽象类的使用与原理

    我们知道Java的三大特性:封装.继承.多态.前两个之前在Java入门(六)已经讲到,现在来讲多态这个特性. 什么是多态? 多态顾名思义即为多种形态的意思 Java中多态的含义: 发送消息给某个对象,让这个对象自行决定采用哪种行为响应这个消息 子类对象的引用赋值给父类引用变量来实现动态的方法调用 Java中形成多态的前提: 继承 父类方法的重写 向上转型 我对多态的解释: 比如我们,是人,也是学生,也是年轻人,我可以用人的身份去做事情,也可以用学生的身份去买学生票,也可以用年轻人的身份做公益,这

  • java多态实现电子宠物系统

    本文实例为大家分享了java多态实现电子宠物系统的具体代码,供大家参考,具体内容如下 效果实现: 代码实现: 1.主人类: public class Master {     //领养     public Pet adopt(String name){         if ("狗狗".equals(name)){             return new Dog();         }else if (name.equals("企鹅")){        

  • Java 继承与多态超详细梳理

    目录 一.继承 1.继承的概念 2.继承的语法 3.父类成员访问 (1)子类中访问父类的成员变量 (2)子类中访问父类的成员方法 4.super关键字 5.子类构造方法 6.super和this 7.代码块执行顺序 8.继承方式 9.final关键字 10.继承和组合 二.多态 1.向上转型 2.重写 3.多态 一.继承 1.继承的概念 继承机制:是面向对象程序设计是代码可以复用的最重要手段,允许程序员在保持原有类特性的基础上进行扩展,增加新的功能,产生的新类,成为派生类/子类.继承主要解决的问

  • Java轻松掌握面向对象的三大特性封装与继承和多态

    目录 1.封装 1.介绍 2.封装的理解和好处 3.封装的实现步骤 2.继承 1.介绍 2.继承的基本语法 3.继承的使用细节 3.super关键字 1.基本介绍 2.基本语法 3.细节与好处 4.super与this的比较 4.方法重写 1.基本介绍 2.注意事项与使用细节 3.重载与重写的比较 3.多态 1.基本介绍 2.具体体现 1.方法的多态 2.对象的多态(重点) 3.多态注意事项和细节讨论 1.多态的前提 2.属性 3.instance of 4.多态的向上转型 5.多态的向下转型

  • Java多态实现原理详细梳理总结

    目录 一.概述 引入 定义 二.多态的体现 三.多态的好处 四.引用类型转换 向上转型 向下转型 为什么要转型 转型的异常 一.概述 引入 多态是继封装.继承之后,面向对象的第三大特性.生活中,比如跑的动作,小猫.小狗和大象,跑起来是不一样的.再比如飞的动作,昆虫.鸟类和飞机,飞起来也是不一样的.可见,同一行为,通过不同的事物,可以体现出来的不同的形态.多态,描述的就是这样的状态. 定义 多态: 是指同一行为,具有多个不同表现形式. 二.多态的体现 多态体现的格式: 父类类型 变量名 = new

  • Java超详细讲解类的继承

    目录 写在前面 1.子类的创建 1.1子类的创建方法 1.2调用父类中特定的构造方法 2.在子类中访问父类成员 3.覆盖 3.1覆盖父类中的方法 3.2用父类的对象访问子类的成员 4.不可被继承的成员和最终类 实例java代码 写在前面 类的继承可以在已有类的基础上派生出来新的类,不需要编写重复的代码,提高了代码的复用性,是面向对象程序设计的一个重要的特点,被继承的类叫做父类,由继承产生的新的类叫做子类,一个父类可以通过继承产生多个子类,但是与C++不同的是Java语言不支持多重继承,即不能由多

  • Java超详细讲解三大特性之一的多态

    目录 多态性 instanceof 关键字的使用 ==和equals()区别 object类中toString()的使用 static关键字的使用 总结 多态性 1理解多态性:可以理解为一个事物的多种形态. 2何为多态性:对象的多态性:父类的引用指向子类的对象(或子类的对象赋给父类的引用) 3多态的使用:虚拟方法调用,有了对象的多态性以后,我们在编译期,只能调用父类中声明的方法,但在运行期,我们实际执行的是子类重写父类的方法,多态性的使用前提:类的继承关系,方法的重写,总结:编译,看左边,运行,

  • Java超详细讲解三大特性之一的继承

    目录 继承的概念 方法的重写 super关键字的使用 super调用构造器 总结 继承的概念 继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为. 通过继承可以快速创建新的类,实现代码的重用,提高程序的可维护性,节省大量创建新类的时间,提高开发效率和开发质量. 继承性的好处: 减少代码的重复 提高代码复用性 便于功能拓展 继承性的格式:class A extends B{} A:子类,派生类,subclass,B: 父类

  • Java超详细讲解三大特性之一的封装

    目录 封装 封装的概念 Java中的包 java中类的成员-构造器 java中的this关键字 总结 说到面向对象则不得不提面向对象的三大特征:封装,继承,多态.那么今天就和大家先来介绍什么是封装. 封装 封装的概念 将类的某些信息隐藏在类的内部,不允许外部程序直接访问,而是通过该类提供的方法来对隐藏的信息进行操作和访问. 为什么需要封装? 当我们创建一个类的对象后,我们可以通过“对象.属性”的方式,对对象的属性进行赋值.这里赋值操作要受到 属性的数据类型和存储范围的制约.除此之外,没有其他制约

  • Java超详细讲解设计模式之一的工厂模式

    目录 工厂模式 1.简单工厂 1.1结构 1.2实现 1.3优缺点 1.4扩展 2.工厂方法 2.1结构 2.2实现 2.3优缺点 3.抽象工厂 3.1结构 3.2实现 3.3优缺点 4.模式扩展 4.1实现 工厂模式 在Java应用程序中对象无处不在,这些对象都需要进行创建,如果创建的时候直接new对象,那么如果我们要更换对象,所有new对象的地方都需要进行更改.违背了软件设计原则中的开闭原则.如果我们使用工厂生产对象,只需要在工厂中关注对象的改变即可,达到了与对象解耦的目的,工厂模式最大的特

  • Java 超详细讲解抽象类与接口的使用

    目录 一.抽象类 1.抽象类的语法 2.抽象类的特性 3.抽象类的作用 二.接口 1.接口的概念 2.接口使用 3.接口特性 4.实现多个接口 5.接口间的继承 6.常用的接口 (1)Comparable接口 (2)Cloneable接口 三.Object类 一.抽象类 在Java中,如果一个类被abstract修饰称为抽象类,抽象类中被abstract修饰的方法称为抽象方法,抽象方法不用给出方法体. 1.抽象类的语法 //抽象类:被abstract修饰的类 public abstract cl

  • Java 超详细讲解异常的处理

    目录 1.异常的概念和体系结构 1.1异常的概念 1.2异常的体系结构及分类 2.异常的处理 2.1防御式编程 2.2异常地抛出 2.3异常的捕获 (1)异常声明throws (2)try-catch捕获并处理 (3)finally 2.4异常的处理流程 3.自定义异常类 1.异常的概念和体系结构 1.1异常的概念 Java中,在程序执行过程中发生的不正常行为称为异常.比如之前一直遇到的: (1)算数异常 System.out.prinntln(10/0); (2)数组越界异常 int[] ar

  • Java超详细讲解接口的实现与用法

    目录 1.接口的定义 2.接口的实现 3.接口的引用 4.接口的继承 5.利用接口实现多重继承 1.接口的定义 接口是一种特殊的抽象类,是Java提供的一个重要的功能,与抽象类不同的是: 接口的所有数据成员都是静态的且必须初始化. 接口中的所有方法必须都是抽象方法,不能有一般的方法. [public] interface 接口名称 [extends  父接口名列表]{    [public] [static] [final]数据类型 成员变量名 = 常量;    ...    [public][

  • Java超详细讲解多线程中的Process与Thread

    目录 进程和线程的关系 操作系统是如何管理进程的 并行和并发 创建线程的方法 串行执行和并发执行 Thread中的一次额重要方法 中断线程 线程等待 线程休眠(sleep) 进程和线程的关系 在操作系统中运行的程序就是进程,比如说QQ,播放器,游戏等等…程序是指令和数据的有序集合,其本身没有任何运行的含义,是一个静态的概念. 进程和线程都是为了处理并发编程这样的场景,但是进程有问题,频繁拆功创建和释放资源的时候效率低,相比之下,线程更轻量,创建和释放效率更高. 进程具有独立性,每个进程有各自独立

随机推荐