Day16-01 P71 面向对象12什么是多态 P72 对象13:instanceof和类型转换 P73 static关键字详解 P74 抽象类 P75 接口的定义与实现 P76N种内部类

Day16-01

P71 面向对象12:什么是多态

在这里插入图片描述

//父类Person
package com.oop.demo06;

public class Person {

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

//子类Student
package com.oop.demo06;

public class Student extends Person{

    //输入了alt+insert选择重写父类Person中的run方法
    @Override
    public void run() {
        System.out.println("重写的父类Person的run方法");
    }

    public void eat(){
        System.out.println("子类Student独有的方法");
    }
}

//执行类main

package com.oop.demo06;

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

        //一个对象的实际类型是确定的
        //new Student();
        //new Person();

        //可以指向的引用类型就不确定了
        //子类Student类型的对象能调用的都是自己的或者继承父类的方法
        Student s1 = new Student();//这个是子类型Student的对象
        //父类Person类型,可以指向子类,但是不能调用子类独有的方法

        Person s2 = new Student();//父类的引用指向子类  //这个是父类型Person的对象
        Object s3 = new Student();
        //Person和Object都是Student的父类型


        s2.run();//输出“重写的父类Person的run方法”  因为子类Student重写了
                //父类Person的方法,虽然Person s2 = new Student();中s2是
               //Person类型的,但是执行的还是子类中重写的run方法(注意:如果子类中
             //没有重写run方法,那还执行父类中Person的run方法输出run )

        s1.eat();//输出“子类Student独有的方法”

        ((Student) s2).eat();//输出“子类Student独有的方法 ”
                 //这里是强制转换,本来由Person s2 = new Student();可
                 // 以知道s2是Person父类型的对象不能用子类型Student独有的方法eat,所以这里用了强制转换,把s2转换成Student类型的对象了就可以用子类Student里面的eat方法了
    }
}

/*
多态注意事项:
1.多态是方法的多态,属性没有多态
2.父类和子类,有联系才能类型转换(指 Student s1 = new Student();Person s2 = new Student();
     这种的对象s1 s2 前边的Student类型和Person类型的转换)否则出现   ClassCsatException异常
3.多态存在条件:有继承关系,方法需要重写,父类引用指向子类(Father f1 = new Son())

     回顾不能被重写的方法类型:
     1.前有 static 的静态方法,它属于类,它不属于实例对象
     2.前有 final 的,final是常量的,被final修饰的就无法改变了它是在常量池里面
     3.前有 private 的,是私有的方法,不能被重写

自己的理解:多态是 比如对子类Student 创建new了两个对象a和b,但是一个是子类型Student的Student a=new Student 一个是父类型Person的 Person b=new Student,如果a和b执行一个同一个方法,完全看这个方法是子类独有还是父类独有还是子类重写的父类的方法 各种情况下的执行结果不一样 这就叫多态
 */





P72 面向对象13:instanceof和类型转换

instanceof 这个关键字可以判断两个类之间有没有父子关系

//父类Person
package com.oop.demo06;

public class Person {

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

//子类Student
package com.oop.demo06;

public class Student extends Person{

    public void go(){
        System.out.println("子类Student中的go方法");
    }


}

//main主程序
package com.oop.demo06;

public class Application {
    public static void main(String[] args) {
        //类型之间的转换: 父(代表高的)  子(代表低的)

//引用类型转换讲解:
        
        //Person父类是高的一方 ,”=“右边的Student子类是低的一方
        Person student = new Student();
        //student.go();编译出错,因为go方法是Student子类独有的,
        //    而对象student前边是Person 是Person类型的, 用不了

        //要想student这个对象用go方法,就要把student对象从Person
        //    父类型转换为Student子类型,就是
        //    把“Person student = new Student();”最左边的Person
        //    转换为Student
        
        //    由Person类型,转Student类型,属于高转低,用强制转换
        ((Student) student).go();//这就是父类Person引用类型
                  // 对象student 强制转换为 子类Student引用类型
                  // 对象student 然后再用子类Student中的go()方
                 // 法的 格式

        //    由Student类型,转Person类型,属于低转高,不用强制转换
        //Student student = new Student();
        //Person person = student;此处把Student类型的
        //           student对象转为高类型Person的对象person
        //    注意:子类引用类型的对象转换为父类引用类型的对象,可能
        //         会丢失自己的本来的一些方法!

        /*
           狂神的 转换 总结(仅作参考):
           1、父类引用类型指向了子类的对象
           2、把子类引用类型转换为父类引用类型,向上转换,不用强制转换
           3、把父类引用类型转换为子类引用类型,向下转换,强制转换
           4、引用类型转换 是为了方便 方法的调用, 就不用重新再new一
              个或几个对象了 减少了重复的代码
         */
    }
}




//instanceof 讲解:



        /*  //父子关系图:
        //Object > String
        //Object > Person > Teacher
        //Object > Person > Student
        Object object = new Student();//object是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);编译报错

        //可以从编译(是否编译出错)和运行(true或false)结果两方面考虑

        //instanceof 总结:
        // A x = new C();
        //System.out.println(x instanceof Y);如果x左边的引用类型A和
        //    Y存在父子关系,则编译不出错可以运行,下一步看 “x =” 右边的创建
        //   类型C是否与 Y 存在父子关系,存在输出 true ,不存在输出false;
        //       如果x左边的引用类型A和instanceof右边的Y没有父子关系,那
        //       编译就出错,更不用说会运行了
        //
    */






P73 面向对象14:static关键字详解

package com.oop.demo07;

public class Student {

    private static int age;//加了static的静态变量 在静态方法区里 多线程!
    private double score;//非静态的变量

    public void run(){

    }

    public static void go(){

    }

    public static void main(String[] args) {
        go();//因为go()方法是static类型的,static是和类一起加载的
             //所以可以直接用
        //run();报错,因为上边的run()方法没有加static,所以不能直接用









        /*Student s1 = new Student();

        System.out.println(Student.age);//静态变量可以通过类名访问
        System.out.println(s1.age);
        System.out.println(s1.score);

         */

    }
}

package com.oop.demo07;

public class Person {


    //匿名代码块:和对象一起产生的,在构造方法之前,可用来赋初始值
    {
        System.out.println("匿名代码块");
    }

    static{
        System.out.println("静态代码块");
    }

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

    public static void main(String[] args) {
        Person person = new Person();//new一个Person的对象
        //输出:静态代码块  //说明先执行的静态代码块
        //     匿名代码块  //第二执行匿名代码块
        //     构造方法    //最后执行构造方法

        System.out.println("=======================");
        Person person1 = new Person();
        //输出:匿名代码块      //这次没有静态代码块,因为静态含static的
        //     构造方法             //东西只执行一次
    }



    /*  {
        //代码块(匿名代码块)
        }

       static {
        //静态代码块
        }

      */
}

package com.oop.demo07;

//静态导入包
import static java.lang.Math.random;//import导入了静态的java.lang.Math.random
import static java.lang.Math.PI;//import导入了静态的java.lang.Math.PI;

public class Test {
    public static void main(String[] args) {
        System.out.println(random());//可以在这个类里面直接用前面静态导入的
        System.out.println(PI);    //包里面的方法
    }
}



P74 面向对象15:抽象类

在这里插入图片描述

package com.oop.demo08;

//class前加 abstract 这个类变成 抽象类
public abstract class Action {

    //约束~有人帮我们实现~
    //方法的public后加 abstract ,变抽象方法,
    // ,只有方法名字,没有方法的实现
    public abstract void doSomething();

//抽象类是个类,需要有子类去继承,所以逃脱不了extends这个关键词
// 但extends有局限性,是单继承的的,但是 接口 是可以多继承的

    /*
       抽象类特点:
       1.不能new这个抽象类(不能被new出一个对象),只能靠子类
       去实现它,就像一个约束,
       2.抽象类里面可以有除抽象方法之外的其他正常方法,但是抽象
       方法所在的类一定是抽象类

    思考?
       1.抽象类有构造器吗?
       2.抽象类存在的意义是什么?
          大批量创建同一类型的不同角色代码时,把相同的内容用普通
          方法留下,不同的内容用抽象方法通过子类去实现
          提高开发效率

     */


}

package com.oop.demo08;

//抽象类(这里A继承了抽象类Action)的所有方法,继承了它的子类
//都必须要实现他的方法,除非这个子类也是abstract类,那就需要
//这个子类的子类去实现他的方法
public class A extends Action{
    @Override
    public void doSomething() {

    }
}



P75 面向对象16:接口的定义与实现

在这里插入图片描述

接口:只有规范,自己无法写方法,专业的约束,实现了约束和实现分离 : 面向接口编程

在这里插入图片描述

//接口

package com.oop.demo09;

//interface关键字代表接口    接口都要有实现类
public interface UserService { //这里用interface代替了class

    //接口中的所有定义的方法其实都是加了抽象abstract的,public abstract
    //接口中的定义都是静态的常量 默认加了public static final,默认不显示

    int AGE = 99;//接口中的定义都是静态的常量
                 //前面默认加了public static final,默认不显示

    void run(String name);
    //这里的前面默认加了public abstract,只不过没有显示

    void add(String name);
    void delete(String name);
    void update(String name);
    void query(String name);
}

//接口
package com.oop.demo09;

public interface TimeService {
    void timer();
}

//上边两个接口的实现类

package com.oop.demo09;

//类,可以 实现 接口  在类名后加implements+接口类名
//实现了接口的类,据需要重写接口中的方法
//这个实现类可以多继承,继承多个接口,如下所示
public class UserServiceImpl implements UserService,TimeService{
    //必须override重写接口中所有方法,这个实现类才不会提示编码错误

    @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 run(String name) {

    }

    @Override
    public void timer() {

    }
}

接口的作用:
1.约束
2.定义一些方法,让不同的人去实现(通过多个实现类继承接口)
3.接口中的方法都是public abstract的
4.接口中的常量都是public static final的
5.接口不能被实例化,因为接口中没有构造方法
6.可以通过implements实现(假继承)多个接口
7.实现类中必须要重写override接口中的所有方法



P76 面向对象17:N种内部类

在这里插入图片描述

内部类实例 1:

//写一个外部类
package com.oop.demo10;

public class Outer {

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

    //类里面再写一个类(简称内部类)(注意是在public class Outer{}两个{}之间)
    public class Inner{
        public void in(){
            System.out.println("这是内部类的方法");
        }
        //内部类可获得外部类的private私有属性 和方法
        //如果内部类class是static的,就不能获得外部类的属性和方法
        public void getID(){
            System.out.println(id);
        }

    }

}

//main 执行程序
package com.oop.demo10;

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

        //new实例化了一个外部类
        Outer outer = new Outer();

        //通过这个外部类的对象outer实例化Outer里的内部类
        Outer.Inner inner = outer.new Inner();
              //输入outer.new Inner();按回车 就行了
        inner.in();
    }
}

实例 2:


package com.oop.demo10;

public class Outer {

    }

//一个Java类(比如这里的demo10.java)中可以有多个class类,但
//是只能有一个 public class ,

class A{

}




实例 3:

//局部内部类(在方法里面的class类)
package com.oop.demo10;

public class Outer {

    //局部内部类(在方法里面的class类)
    public void method(){

        class Inner{
            public void in(){
                
            }

        }
    }

    }

实例4:拓展

//拓展:
package com.oop.demo10;

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

        //匿名内部类
        //没有名字初始化类,不用将实例保存到变量中
        new Apple().eat();//直接用Apple类中的eat()方法
        //这是匿名对象的使用,new Apple没有赋予对象名字

        UserService userService = new UserService() {
                           //在这个Test类里new了下面的接口
            @Override     //new完接口要重写接口里的方法,否则报错
            public void hello() {

            }
        };


    }
}

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

interface UserService{ //这是一个接口
    void hello();
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值