Java面向对象 12 - 17


Java面向对象 12 - 17

Java面向对象12 - 什么是多态

  • 动态编译 : 增强可扩展性
  • 即同一个方法可以根据发送对象的不同而采用多种不同的行为方式
  • 一个对象的实际类型是确定的,但可以指向对象的引用的类型有很多(父类,有关系的类)
  • 多态存在条件
    • 有继承关系
    • 子类重写父类方法
    • 父类引用指向子类对象
  • 注意:多态是方法的多态,属性没有多态
package Demo07;

public class Person {

    public void run(){
        System.out.println("person");
    }

    public void sleep(){
        System.out.println("sleep");
    }
}
package Demo07;

public class Student extends Person{

    @Override
    public void run() {
        System.out.println("Student");
    }

    public void eat(){
        System.out.println("eat");
    }
}
package Demo07;

public class Application {
    public static void main(String[] args) {
        //一个对象的实际类型是确定的
        //new Student();
        //new Person();

        //可以指向的引用类型就不确定了:父类引用指向子类

        //Student 能调用的方法都是自己的或者继承父类的
        Student s1 = new Student();
        //Person 父类型,可以指向子类,但是不能调用子类独有的方法
        Person s2 = new Student();
        Object s3 = new Student();

        //对象能执行哪些方法,主要看对象左边的类型,和右边关系不大
        // s2.eat(); 无法执行,因为Person类里没有eat()
        s2.run();
        s1.run(); //都执行的子类的方法,原因是s2虽然企图去执行父类的方法
                  //但是由于子类复写了这个方法,所以执行子类的去了
        s2.sleep();//执行了父类的sleep方法,因为子类没复写
        s1.sleep();//因为子类继承了父类,因为子类没复写,所以有个一样的sleep方法
    }
}
Student
Student
sleep
sleep
  • 经典例子
package Demo07;

class A {
    public String show(D obj) {
        return ("A and D");
    }

    public String show(A obj) {
        return ("A and A");
    }

}

class B extends A{
    public String show(B obj){
        return ("B and B");
    }

    public String show(A obj){
        return ("B and A");
    }
}

class C extends B{

}

class D extends B{

}

public class Test {
    public static void main(String[] args) {
        A a1 = new A();
        A a2 = new B();
        B b = new B();
        C c = new C();
        D d = new D();

        System.out.println("1--" + a1.show(b));
        System.out.println("2--" + a1.show(c));
        System.out.println("3--" + a1.show(d));
        System.out.println("4--" + a2.show(b));
        System.out.println("5--" + a2.show(c));
        System.out.println("6--" + a2.show(d));
        System.out.println("7--" + b.show(b));
        System.out.println("8--" + b.show(c));
        System.out.println("9--" + b.show(d));
    }
}
1--A and A
2--A and A
3--A and D
4--B and A
5--B and A
6--A and D
7--B and B
8--B and B
9--A and D

Java面向对象13 - instanceof和类型转换

  • instanceof 用来判断两个类有没有父子关系
package Demo08;

public class Person {
}
package Demo08;

public class Student extends Person{
}
package Demo08;

public class Teacher extends Person{

}
package Demo08;

public class Application {
    public static void main(String[] args) {

        // Object > Person > Student
        // 前三个是true,因为创建的object对象是Student类的实例,只不过指向了Object类
        Object object = new Student();

        System.out.println(object instanceof Student); // true
        System.out.println(object instanceof Person); // true
        System.out.println(object instanceof Object); // true
        System.out.println(object instanceof Teacher); // false
        System.out.println(object instanceof String); // false

        System.out.println("===================================");

        Person person = new Student();

        System.out.println(person  instanceof Student); // true
        System.out.println(person  instanceof Person); // true
        System.out.println(person  instanceof Object); // true
        System.out.println(person instanceof Teacher); // false
//        System.out.println(person  instanceof String); //编译时报错

        System.out.println("===================================");

        Student student = new Student();

        System.out.println(student instanceof Student); // true
        System.out.println(student instanceof Person); // true
        System.out.println(student instanceof Object); // true
//        System.out.println(student instanceof Teacher); // 编译时报错
//        System.out.println(student instanceof String); // 编译时报错
    }
}
  • 类型转换
    • 子类转换为父类,低转高,向上转型,可能会丢失一些自己的本来的方法
    • 父类转换为子类,高转低,向下转型,需要强制转换
package Demo09;

public class Person {

    public void run(){
        System.out.println("run");
    }
}
package Demo09;

public class Student extends Person{

    public void go(){
        System.out.println("go");
    }
}
package Demo09;

public class Application {
    public static void main(String[] args) {
        //这个是Student 转 Person,属于低转高                 
        Person obj = new Student();
//        obj.go();// 报错因为Person类里面没有go方法           
        // 通过转化把 obj 再度转换为 Student 类型               
        Student student = (Student) obj;
        student.go();
        // ((Student) obj).go(); 合成一句话也可以           


    }
}  
go

Java面向对象14 - static关键字详解

  • 代码块
package Demo10;

public class Person {
    //2 : 起到赋初始值作用
    {
        System.out.println("匿名代码块");
    }

    //1 : 只执行一次
    static {
        System.out.println("静态代码块");
    }

    //3
    public Person(){
        System.out.println("构造方法");
    }

    public static void main(String[] args) {
        Person p1 = new Person();
        System.out.println("===============================");
        Person p2 = new Person();
    }
}
静态代码块
匿名代码块
构造方法
===============================
匿名代码块
构造方法
  • static 关键字
package Demo10;

public class Student {

    private static int age; // 静态变量 多线程
    private double score; // 非静态变量

    public void run(){

    }

    public static void go(){

    }


    public static void main(String[] args) {
        Student s1 = new Student();

        System.out.println(Student.age);
//        System.out.println(Student.score);//报错
        System.out.println(s1.age);
        System.out.println(s1.score);
    }
}
  • final
    • 被final修饰的class不能被继承了

Java面向对象15 - 抽象类

package Demo11;

// abstract 抽象类
public abstract class Action {

    // 抽象方法,不用写具体实现
    public abstract void doSomething();

    // 1. 不能new这个类,只能子类去实现它
    // 2. 抽象类里可以写普通方法,但是如果类里有抽象方法,那么一定得是抽象类

    // 存在构造器
}
package Demo11;
// 抽象类所有方法子类必须实现,除非子类也是abstract
public class A extends Action{

    @Override
    public void doSomething() {

    }
}

Java面向对象16 - 接口的定义与实现

  • 普通类:只有具体实现
  • 抽象类:具体实现和规范都有
  • 接口:只有规范
package Demo12;

public interface UserService {
    // 属性默认是常量 public static final,但是很少在接口里定义常量,多为方法
    int AGE = 99;
    //接口中所有定义默认都是public abstract
    void add(String name);
    void delete(String name);
    void update(String name);
    void query(String name);
}
package Demo12;

public interface TimeService {
    void timer();
}
package Demo12;

// 类可以实现接口
// 类只能单继承,包括抽象类
// 但接口可以多实现,不能被继承()
// 实现接口的类一定要实现接口中的方法
public class UserServiceImpl implements UserService,TimeService {
    @Override
    public void add(String name) {

    }

    @Override
    public void delete(String name) {

    }

    @Override
    public void update(String name) {

    }

    @Override
    public void query(String name) {

    }

    @Override
    public void timer() {

    }
}

作用:

  1. 约束
  2. 定义一些方法让不同的人实现
  3. public abstract
  4. public static final
  5. 接口不能被实例化,接口没有构造方法
  6. implements可以实现多个接口
  7. 必须要重写接口中的方法

Java面向对象17 - N种内部类

在一个类的内部再定义一个类

  1. 成员内部类
  2. 静态内部类
  3. 局部内部类
  4. 匿名内部类
  • 成员内部类
package Demo13;

public class Outer {

    private int id;
    public void out(){
        System.out.println("这是外部类的方法");
    }

    public class  Inner{
        public void in(){
            System.out.println("这是内部类");
        }

        //获得外部类的私有属性
        public void getID(){
            System.out.println(id);
        }
    }

}
package Demo13;

public class Application {
    public static void main(String[] args) {
        Outer outer = new Outer();

        //通过外部类实例化内部类
        Outer.Inner inner = outer.new Inner();
        inner.in();
        inner.getID();
    }

}
这是内部类
0
  • 静态内部类

如果以上的 Inner class 是 static 类,那么 getID() 方法将会报错,因为static在一开始就执行了,但是id并不是一个static的东西,所以id还尚未出现,所以报错。除非id也是static。

  • 局部内部类
package Demo13;

public class Outer {

    public void method(){
        //和局部变量一样,这种类创建在方法里
        class Inner{

        }
    }

}
package Demo13;

public class Test {
    public static void main(String[] args) {
        //没有名字初始化类,不用把实例化保存到变量中
        new Apple().eat();
        //这个new一个接口也是匿名内部类
        UserService userService = new UserService() {
            @Override
            public void hello() {

            }
        };

    }
}

class Apple{
    public void eat(){
        System.out.println("1");
    }
}

interface UserService{
    void hello();
}

Author: Liang Junyi
Reprint policy: All articles in this blog are used except for special statements CC BY 4.0 reprint policy. If reproduced, please indicate source Liang Junyi !
  TOC