java面向对象

面向对象编程

面向过程 & 面向对象

  • 面向过程思想
    • 步骤清晰简单,第一部做什么,第二步做什么...
    • 面向过程适合处理一些较为简单的问题。
  • 面向对象思想
    • 物以类聚,分类的思维模式,思考问题首先会解决问题需要哪些分类,然后对这些分类进行单独思考。最后,才对某个分类下的细节进行面向过程的思索。
    • 面向对象适合处理复杂的问题,适合处理需要多人协作的问题!
  • 对于描述复杂的事物,为了从宏观上把握、从整体上合理分析,我们需要使用面向对象的思路来分析整个系统。但是,具体到微观操作,仍然需要面向过程的思路去处理。

什么是面向对象

  • 面向对象编程(Object-Oriented Programming,OOP)
  • 面向对象编程的本质就是:以类的方式组织代码,以对象的形式组织(封装)数据。
  • 抽象
  • 三大特征:
    • 封装
    • 继承
    • 多态
  • 从认识论角度考虑是先有对象后有类。对象,是具体的事物。类,是抽象的,是对对象的抽象
  • 从代码运行角度考虑是先有类后有对象。类是对象的模板。

回顾方法及加深

  • 方法的定义

    • 修饰符
    • 返回类型
    • break和return的区别
      • break:跳出switch,结束循环
      • return:结束方法,返回一个结果!
    • 方法名
    • 参数列表
    • 异常抛出
      • 后面讲解
  • 方法的调用

    • 静态方法
    • 非静态方法
    • 形参和实参
    • 值传递和引用传递
    • this关键字

Demo01

package 方法的回顾及加深;


import java.io.IOException;

//回顾方法的定义
public class Demo01 {
    //Demo01:类

    //main:方法
    public static void main(String[] args) {

    }

     /*
     修饰符 返回值类型 方法名(...){
           //方法体
         return  返回值;

     }
      */
    public String sayHello(){

        return "hello,world";
    }

    public void hello(){

        return;
    }

    public int max (int a,int b){
        return a>b ?a:b;//三元运算符
    }


    //抛出异常:
    public void readFile(String file) throws IOException{

    }
}

Demo02

package 方法的回顾及加深;

//回顾方法的调用
public class Demo02 {
    public static void main(String[] args) {

     //若要调用student中的say方法


        //1.若say为静态方法,则可以通过类名和方法名直接调用。如下:
        Student2.say();

        //2.若say为非静态方法,无法直接调用,需要实例化这个类,用new。如下:
        new Student2().speak();
        //或
        Student2 student2 = new Student2();
        //对象类型  对象名 = 对象值

        //3.然后可以用这个对象

        student2.speak();

    }

    //若两个方法都是静态的或都是非静态的,则可以互相调用;若一个为静态一个为非静态,则不能互相调用。
    public void a(){

        b();
    }


    public void b(){

    }
}

Demo03

package 方法的回顾及加深;

import javax.xml.ws.soap.Addressing;

//回顾型参与实参
public class Demo03 {

    public static void main(String[] args) {

        //形式参数和实际参数的类型要对应!
        int add = new Demo03().add(1, 2);
        System.out.println(add);

    }
    public int add(int a,int b){
        return a+b;
    }
}

Demo04

package 方法的回顾及加深;

//回顾方法的值传递
public class Demo04 {

    public static void main(String[] args) {

        int a = 1;
        System.out.println(a);//输出1

        Demo04.change(a);
        System.out.println(a);//输出1

    }

    //返回值为空
    public static void change(int a){
        a=10;
    }
}

Demo05

package 方法的回顾及加深;

//回顾方法的引用传递
public class Demo05 {

    //引用传递一般传递一个对象,但本质还是值传递

    public static void main(String[] args) {
        Person a = new Person();

        System.out.println(a.name);//输出null


        Demo05.change(a);

        System.out.println(a.name);//输出hcss

    }
    public static void change(Person a){
         //a是一个对象,指向的是---->Person a = new Person();这是一个具体的人,可以改变属性!
        a.name ="hcss";
    }
}

//一个类中只能有一个public class,但可以有多个class类。
//定义了一个Person类,有一个name属性。
class Person{
    String name;//若不定义属性值,默认的应该是null。
}

定义的类:

package 方法的回顾及加深;

//一个学生类
public class Student2 {

    //定义一个静态方法
    public static void say(){
        System.out.println("学生说话了!");
    }

    //定义一个非静态方法
    public void speak(){
        System.out.println("学生说话了!");
    }
}

类与对象的关系

  • 类是一种抽想的数据类型,它是对某一类事物整体描述/定义,但是并不能代表某一个具体的事物。
    • 动物、植物、手机、电脑......
    • Person类、Pet类、Car类,这些类都是用来描述/定义某一类具体的事物应该具备的特点和行为。
  • 对象是抽想概念的具体实例
    • 张三就是人的一个具体实例,张三家里的旺财就是狗的一个具体实例。
    • 能够体现出特点,展现出功能的是具体的实例,而不是一个抽象的概念。

类的调用:

1.实例化类语法:类名 对象名 = new 类型();

​ 类名 对象名 = new 类型([实参列表]);

2.调用类中的属性:对象名.属性名

3.调用类中的方法:对象名.方法名([实参列表]);

构造方法:用于实例化类的对象的方法称为构造方法

有参构造方法:实例化对象的同时为类中的成员属性进行赋值

无参构造方法:实例化对象的时候对成员属性不进行赋值

语法格式:访问修饰符 方法名(){ //无参构造方法

​ }

​ 访问修饰符 方法名([形参列表]){

​ this.成员属性 = 形参;

​ ...........

​ }

创建与初始化对象

  • 使用new关键字创建对象

  • 使用new关键字创建的时候,除了分配内存空间之外,还会给 创建好的对象 进行默认的初始化以及 对类中构造器的调用。

  • 类中的构造器也称为构造方法,是在进行创建对象的时候必须要调用的。并且构造器有以下两个特点:

    • 1.必须和类的名字相同
    • 2.必须没有返回类型,也不能写void
  • 构造器必须要掌握

  • 构造器的作用:1.实例化初始值。谁用new关键字时,本质是在调用构造器。

    ​ 2.用来初始化对象的值。

  • 注意点:一旦定义了有参构造,无参构造就必须显示定义。

  • 快捷键Fn+Alt+Insert:生成构造器

  • this. = ,代表当前类,等号后一般为参数传进来的值。

    • 可以调用成员属性:this.成员属性名
    • 可以调用成员方法:this.成员方法名([参数列表]);

Demo01

package 创建与初始化对象;

public class Person {

    /*
    虽然什么都没写,但仍能在测试类中new处一个person方法
    一个类什么都不写,它也会存在一个方法(构造器)。
    构造器查看:打开项目中out中对应的方法的class文件。
     */

    String name;

    //手写一个显示的构造器
    //构造器有一下两个特点:-1.必须和类的名字相同
    //-2.必须没有返回类型,也不能写void
    //无参构造:
    public Person(){

    }
    /*
    构造器的作用:1.实例化初始值。使用new关键字时,本质是在调用构造器。当new这个person时,程序会走构造器,就对name初始化了。
                2.用来初始化对象的值
     */


    //有参构造:
    public Person(String a){
        this.name = a;
    }
    //注意点:一旦定义了有参构造,无参构造就必须显示定义。


    //快捷键Fn+Alt+Insert:生成构造器

}
//person的测试类:
/*
 public static void main(String[] args) {

        //使用new关键词实例化了一个对象
        Person person = new Person("hcss");


        System.out.println(person.name);//hcss
    }
 */

Demo02

package 创建与初始化对象;

//学生类
public class Student1 {

    //类中有一个个属性:字段。
    String name;//默认值:null
    int age;//默认值:0



    //类中还有方法
    public void study(){
        System.out.println(this.name+"在学习");//this代表当前这个类,相当于这个学生在学习

    }
}
/*
总结:类是一个抽象的模板,而通过new关键词可以创建不一样的具体的实例;
 给模板赋值,就是各种不同的实例。

 如:
 person会有不同的属性;
 person===>身高、体重、年龄、性别、国籍、民族
 通过不同的属性组合来确定唯一的一个person。
 */


//student的测试类:
/*
 public static void main(String[] args) {

           //类:类是抽象的,若要引用类,则需要实例化出来
        //通过new对类进行实例化。如:new Student();
        //类实例化后会返回一个自己的对象
        //student对象就是一个Student类的具体实例!如下:

        Student student = new Student();

        Student xiaoming = new Student();
        Student xh = new Student();

        xiaoming.name = "小明";
        xiaoming.age = 3;

        System.out.println(xiaoming.name);
        System.out.println(xiaoming.age);

        xh.name = "小红";
        xh.age = 3;

        System.out.println(xh.name);
        System.out.println(xh.age);

    }
 */

创建对象内存分析

![屏幕截图 2021-09-10 093633](C:\Users\huahuahua\Pictures\屏幕截图 2021-09-10 093633.png)

Demo01

package 创建对象内存分析;

public class Pet {

    //类中存在默认的无参构造

    public String name;
    public int age;

    public void shout() {

        System.out.println("叫了一声");
    }
}

小结类与对象

1.类与对象

​ 类是一个抽象的模板,对象是一个具体的实例

2.方法

​ 方法的定义与调用

3.对象的引用

​ 引用类型

​ 基本类型(8个)

​ 对象是通过引用来操作的:栈---->堆(引用就是指向对象的

​ 一个地址)

4.对象的属性(字段)(成员变量)

​ 默认初始化:

​ 数字: 0 0.0

​ char: u0000

​ boolean: false

​ 引用:null

​ 定义:

​ 修饰符 属性类型 属性名 = 属性值!

5.对象的创建和使用

​ -必须使用new 关键字创造对象,必须要有构造器

​ -对象的属性

​ Person hcss = new Person();

​ hcss.name

​ -对象的方法 hcss.sleep();

​ 6.类

​ 静态的属性 (属性)

​ 动态的行为 (方法)

注意:

1.构造方法名和类型必须保持一致
2.没有访问者这一说法
3.如果在⼀个类中显示的定义了有参构造⽅法,则隐形⽆参构造将不存在。此时建议将 ⽆参构造⽅法显示定义
4.每个类都有构造⽅法,如果没有显示地为类定义构造⽅法,Java编译器将会为该类提供⼀个默认隐形 ⽆参构造⽅法
5.在创建⼀个类的对象时,⾄少要调⽤⼀个构造⽅法。
6.⼀个类中可以有多个构造⽅法,它们之间构成了重载,即构造方法重载。

封装

  • 改露的露,该藏的藏
    • 我们程序要追求”高内聚,低耦合“。高内聚就是类的内部数据操作细节自己完成,不允许外部干涉;低耦合:仅暴露少量的方法给外部使用。
  • 封装(数据的隐藏)
    • 通常,应禁止直接访问一个对象中数据的实际表示,而应通过操作接口来访问,这称为信息隐藏。
  • 记住这句话就够了:属性私有,get/set

封装的意义:

  1. 提高程序的安全性,保护数据
  2. 隐藏代码的实现细节
  3. 统一接口
  4. 提高系统的可维护性

Demo01

package 封装;

//类
public class Student {

    //封装大部分用于属性

    //private:私有


    //属性私有:
    private String name;//名字

    private int id;//学号

    private char sex;//性别

    private int age;//年龄


    //提供一些可以操作这个属性的方法!
    //提供一些public的get、set的方法


    //get:获得这个数据
    public String getName(){
        return this.name;
    }

    //set:给这个数据设置值

    public void setName(String a){
        this.name = a;
    }



    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public char getSex() {
        return sex;
    }

    public void setSex(char sex) {
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        if (age>120 ||age<0){
            this.age=3;
        }else {
           this.age = age;
        }
        //若数值不合法,可在set中进行设置

        //快捷键:鼠标右键选择点击生成,选择get/set生成。

    }
}
//Student的测试类:
/*
 public static void main(String[] args) {

        Student s1 = new Student();

        String name = s1.getName();

        s1.setName("hcss");

        System.out.println(s1.getName());
        
        

        int age = s1.getAge();

        s1.setAge(1);//不合法的

        System.out.println(s1.getAge());


    }
 */

继承

  • 继承的本质是对某一批类的抽象,从而实现对现实世界更好的建模。

  • extends的意思是”扩展“。子类是父类的扩展。

  • java中类只有单继承,没有多继承!

  • 继承是类和类之间的一种关系。除此之外,类和类之间的关系还有依赖、组合、聚合等。

  • 继承关系的两个类,一个为子类(派生类),一个为父类(基类)。子类继承父类,使用关键字extends来表示。

  • 子类和父类之间,从意义上讲应该具有”is a“的关系。

  • object类

  • super

  • 方法重写

  • super注意点:

    1. super调用父类的构造方法,必须在构造方法的第一个

    2. super必须只能出现在子类的方法或者构造方法中

    3. super 和 this 不能同时调用构造方法!

    4. 对比this:

      1. 两者代表的对象不同:this代表本身调用者这个对象;super代表父类对象的引用。

      2. 使用前提不一致:this没有继承也可以使用;super只能在继承条件下(有继承关系时)才可以使用 。

      3. 调用构造方法不同:

        ​ this();调用本类的构造

        ​ super();调用父类的构造

  • 重写:需要有继承关系,子类重写父类的方法!

    1. 方法名必须相同

    2. 参数列表必须相同

    3. 修饰符:范围可以扩大:public > Protected > Default > private

    4. 抛出的异常:范围可以被缩小,但不能扩大

      ​ ClassNotFoundException --> Exception(大)

    5. 重写,子类的方法和父类必须要一致;方法体不同!

  • 为什么要重写:

    1. 父类的功能,子类不一定需要,或者不一定满足!
  • 快捷键:鼠标右键选择点击生成,选择Override

Demo01_Student

package 继承;

//Student(子类/派生类)    is    人
public class Student extends Person{  //extends:继承Person类

    //Student想用Person类除了继承,还有组合的方法。如下:
    //Person person;

    //子类继承了父类,就会拥有父类的全部方法!


    //快捷键Ctrl+H:打开继承结构。
     /*===============================================================
    =================================================================
    =================================================================
    =================================================================
     */
    //super:

    //怎样在子类(student)中访问父类(person)的属性呢?  用super访问。

    private String name = "pqy";
    public void test (String name){
        System.out.println(name);//花朝十三
        System.out.println(this.name);//pqy
        System.out.println(super.name);//hcss
    }


    /*==================================================*/

    public void print(){
        System.out.println("Student");
    }
    public void test1 (String name){
        print();//Student
        this.print();
        super.print();//Person
    }

    /*===============================================================
    =================================================================
    =================================================================
    =================================================================
     */

    public Student() {
        System.out.println("Student(子类)的无参构造执行了");
    }
    /*
    父类的无参构造先执行,其次执行子类的无参构造。
    所以有一句隐藏代码:super(),默认子类调用了父类的无参构造,super()。
    调用父类的构造器,必须要在子类构造器的第一行。
     */

}
//测试类:
/*
public static void main(String[] args) {

        Student student = new Student();

        student.say();

        System.out.println(student.money);

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

        //在java中,所有的类都默认直接或者间接继承object类

        Person person = new Person();

        //若类中没有任何方法,在调用类时,仍然有很多没有定义过的方法可以使用
        //因为有一个隐藏的类在object类下。而在Java中,所有的类都默认直接或者间接继承object类
        //如:

        person.hashCode();
        person.toString();
        person.notify();
    }
 */
//super测试类:
/*

 */

Demo02_Teacher

package 继承;

//Teacher(子类/派生类)  is   人
public class Teacher extends Person{
}

Demo03_Person

package 继承;

//Person类    人:父类
public class Person {

    //子类可以继承父类的所有方法

    //修饰符:
    //public
    //private
    //default(默认的)
    //protected(受保护的)

    public int money = 10_0000_0000;


    public void say() {

        System.out.println("说了一句话。");
    }
    /*===============================================================
    =================================================================
    =================================================================
    =================================================================
     */
    //super:
    protected String name = "hcss";

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

    /*若修饰符变为私有的private,则不能被调用,
    因为私有的东西无法被继承。
     */

    /*===============================================================
    =================================================================
    =================================================================
    =================================================================
     */
    //一个无参构造器:
    public Person() {
        System.out.println("Person(父类)无参执行了");
    }
}



//测试类:
/*
public static void main(String[] args) {

        Student student = new Student();

        student.say();

        System.out.println(student.money);

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

        //在java中,所有的类都默认直接或者间接继承object类

        Person person = new Person();

        //若类中没有任何方法,在调用类时,仍然有很多没有定义过的方法可以使用
        //因为有一个隐藏的类在object类下。而在Java中,所有的类都默认直接或者间接继承object类
        //如:

        person.hashCode();
        person.toString();
        person.notify();

    }
 */
//super测试类:
/*

 */

Demo04_继承-方法重写

package 继承_方法重写;

public class A extends B {

    //Override   重写
    @Override //注解:有功能的注释!
    public void test() {
        System.out.println("A=>test()");
    }
}

//测试类:
/*
 public static void main(String[] args) {

        //静态方法和非静态方法区别很大
        //当方法为静态方法时,方法的调用只和等号左边,即定义的数据类型有关。
        //当为非静态方法时,则重写。


        A a = new A();
        a.test();//程序走A类中的方法



        //父类的引用指向了子类
        B b = new A();//子类重写了父类的方法
        b.test();//程序走B类中的方法

        //重写只和非静态方法有关。

        //重写的关键词只能是public,不能是私有的。


    }
 */

Demo05_继承-方法重写

package 继承_方法重写;


//重写都是方法的重写,和属性无关。
public class B {

    public  void test(){

        System.out.println("B=>test()");
    }

}
//测试类:
/*
 public static void main(String[] args) {

        //静态方法和非静态方法区别很大
        //当方法为静态方法时,方法的调用只和等号左边,即定义的数据类型有关。
        //当为非静态方法时,则重写。


        A a = new A();
        a.test();//程序走A类中的方法



        //父类的引用指向了子类
        B b = new A();//子类重写了父类的方法
        b.test();//程序走B类中的方法

        //重写只和非静态方法有关。

        //重写的关键词只能是public,不能是私有的。


    }
 */

多态

  • 即同一个方法可以根据发送对象的不同而采用多种不同的行为方式。

  • 一个对象的实际类型是确定的,但可以指向对象的引用的类型有很多

  • 多态存在的条件

    • 有继承关系
    • 子类重写父类
    • 父类的引用指向子类对象
  • 注意:多态是方法的多态,属性没有多态性。

  • instanceof,(类型转换)引用类型

    • 作用:判断一个对象是什么类型
  • 多态注意事项:

    1. 多态是方法的多态,属性没有多态

    2. 父类和子类有关系,才能进行转换;若强转则会出现转换异常:ClassCastException!

    3. 多态存在的条件:3.1继承关系;

      ​ 3.2方法需要重写;(若子类和父类存在同一种方法,在调用方法时,执行子类的方法。)

      ​ 3.3父类引用指向子类对象!Father f1= new Son();

  • 不能被重写的方法:

    1. static是静态方法,属于类,它不属于实例。
    2. final是常量的,无法改变
    3. private是私有方法,不能重写。
    • 1.父类的引用指向子类的对象
    • 2.如果把子类转换为父类,是向上转型,不用强制转换
    • 3.如果把父类转换为子类,是向下转型,需要强制转换
    • 4.方便方法的调用,减少重复的代码!更简洁

    抽象:封装、继承、多态

Demo01

package 多态;

public class Student extends Person{

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

    public void eat(){
        System.out.println("eat");
    }
}
//测试类:
/*
 //一个项目应该只存在一个main方法,作为总的测试类
    public static void main(String[] args) {

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

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

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


        //对象能执行哪些方法,主要看对象左边的类型,和右边关系不大!
        ((Student)s2).eat();//子类重写了父类的方法,执行了子类的方法
        s1.run();

    }
 */

Demo02

package 多态;

public class Person {

    public void run(){
        System.out.println("run");
    }
}
//测试类:
/*
 //一个项目应该只存在一个main方法,作为总的测试类
    public static void main(String[] args) {

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

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

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


        //对象能执行哪些方法,主要看对象左边的类型,和右边关系不大!
        ((Student)s2).eat();//子类重写了父类的方法,执行了子类的方法
        s1.run();

    }
 */

Dome03_instanceof

package 多态_instanceof;

public class Person {

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

}


//测试类:
/*
 public static void main(String[] args) {

        //Object > String
        //Object > Person > Teacher
        //Object > Person > Student
        Object object = new Student();

        //样式:System.out.println(   X instanceof Y);//能不能编译通过;若X与Y之间有父子关系,则编译通过;X指向的类型是Y的子类型或与Y有关,则通过。

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

        System.out.println(object instanceof Student);//ture//通过instanceof判断当前对象object是否是Student类型的。
        System.out.println(object instanceof Person);//ture
        System.out.println(object instanceof Object);//ture
        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);//ture
        System.out.println(person instanceof Object);//ture
        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);//ture
        System.out.println(student instanceof Object);//ture
        //System.out.println(student instanceof Teacher);//编译报错!
        //System.out.println(student instanceof String);//编译报错!

    }
 */

//转换测试类:
/*
 public static void main(String[] args) {

        //类型之间的转换: 父类高子类低

        //Object > String
        //Object > Person > Teacher
        //Object > Person > Student

        //Student obj = new Student();
        //Student类能够直接转为Person类,如下:  因为Person类是高的一方,Student是低的一方,能够直接转换。

        //高                    低
        Person obj = new Student();

        Student student = (Student) obj;
        ( (Student) obj).go();

        //子类转换为父类,可能会丢失自己的本来的一些方法!
        Student student1 = new Student();
        student.go();
        Person person = student;


    }
 */

Dome04_instanceof

package 多态_instanceof;

public class Student extends Person{

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



}
//测试类:
/*
 public static void main(String[] args) {

        //Object > String
        //Object > Person > Teacher
        //Object > Person > Student
        Object object = new Student();

        //样式:System.out.println(   X instanceof Y);//能不能编译通过;若X与Y之间有父子关系,则编译通过;X指向的类型是Y的子类型或与Y有关,则通过。

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

        System.out.println(object instanceof Student);//ture//通过instanceof判断当前对象object是否是Student类型的。
        System.out.println(object instanceof Person);//ture
        System.out.println(object instanceof Object);//ture
        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);//ture
        System.out.println(person instanceof Object);//ture
        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);//ture
        System.out.println(student instanceof Object);//ture
        //System.out.println(student instanceof Teacher);//编译报错!
        //System.out.println(student instanceof String);//编译报错!

    }
 */

//转换测试类:
/*
 public static void main(String[] args) {

        //类型之间的转换: 父类高子类低

        //Object > String
        //Object > Person > Teacher
        //Object > Person > Student

        //Student obj = new Student();
        //Student类能够直接转为Person类,如下:  因为Person类是高的一方,Student是低的一方,能够直接转换。

        //高                    低
        Person obj = new Student();

        Student student = (Student) obj;
        ( (Student) obj).go();

        //子类转换为父类,可能会丢失自己的本来的一些方法!
        Student student1 = new Student();
        student.go();
        Person person = student;


    }
 */

Demo05_instanceof

package 多态_instanceof;

public class Student extends Person{

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



}
//测试类:
/*
 public static void main(String[] args) {

        //Object > String
        //Object > Person > Teacher
        //Object > Person > Student
        Object object = new Student();

        //样式:System.out.println(   X instanceof Y);//能不能编译通过;若X与Y之间有父子关系,则编译通过;X指向的类型是Y的子类型或与Y有关,则通过。

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

        System.out.println(object instanceof Student);//ture//通过instanceof判断当前对象object是否是Student类型的。
        System.out.println(object instanceof Person);//ture
        System.out.println(object instanceof Object);//ture
        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);//ture
        System.out.println(person instanceof Object);//ture
        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);//ture
        System.out.println(student instanceof Object);//ture
        //System.out.println(student instanceof Teacher);//编译报错!
        //System.out.println(student instanceof String);//编译报错!

    }
 */

//转换测试类:
/*
 public static void main(String[] args) {

        //类型之间的转换: 父类高子类低

        //Object > String
        //Object > Person > Teacher
        //Object > Person > Student

        //Student obj = new Student();
        //Student类能够直接转为Person类,如下:  因为Person类是高的一方,Student是低的一方,能够直接转换。

        //高                    低
        Person obj = new Student();

        Student student = (Student) obj;
        ( (Student) obj).go();

        //子类转换为父类,可能会丢失自己的本来的一些方法!
        Student student1 = new Student();
        student.go();
        Person person = student;


    }
 */

抽象类

  • abstract修饰符可以用来修饰方法也可以修饰类,如果修饰方法,那么该方法就是抽象方法;如果修饰类,那么该类就是抽象类。

  • 抽象类中可以没有抽象方法,但是有抽象方法的类一定要声明为抽象类。

  • 抽象类,不能使用new关键字来创建对象,它是用来让子类继承的。

  • 抽象方法,只有方法的声明,没有方法的实现,它是用来让子类实现的。

  • 子类继承抽象类,那么就必须要实现抽象类没有实现的抽象方法,否则该子类也要声明为抽象类。

抽象类的特点:

1.不能new这个抽象类,只能靠子类去实现它,是一个约束。

2.抽象类中可以写普通的方法

3.抽象方法必须在抽象类中

4.存在的意义:提高开发效率

Demo01

package 抽象类;

//抽象类的所有方法,继承了它的子类,都必须要实现它的方法,除非子类也为抽象类
public class A extends Action{

    @Override
    public void dosomething() {

    }
}

Demo02

package 抽象类;

//在一个类中使用abstract,那就变成了一个抽象类。
public abstract class Action {


    //在一个方法中使用abstract,就是抽象方法;只有方法的名字,没有方法的实现。
    public abstract void dosomething();

    //抽象类的本质还是类,类是需要用rxtends继承的,但extends是单继承,在java中,接口可以多继承。

}

接口

  • 普通类:只有具体实现

  • 抽象类:具体实现和规范(抽象方法)都有

  • 接口:只有规范!自己无法写方法,是专业的约束,主要是约束和实现分离。

  • 如果一个类中的全部方法都是抽象方法,全部属性都是全局常量,那么此时就可以将这个类定义成一个接口。

  • 定义格式:

    interface  接口名称{
        全局常量;
        抽象方法;
    }
    
  • 接口就是规范,定义的是一组规则,体现了现实世界中“如果你是....则必须能....的思想。
  • 接口的本质是契约,就像法律一样。制定好大家都遵守。
  • OO的精髓,是对对象的抽象,最能体现这一点的就是接口。为什么我们讨论设计 模式都只针对具备了抽象能力的语言(比如c++、java、c#等),就是因为设计模式所研究的,实际上就是如何合理的去抽象。

接口的作用:

1.约束

2.定义一些方法,让不同的人实现

3.接口中默认的方法是public abstract

4.接口中常量的默认是public static final

5.接口不能直接被实例化,因为接口中没有构造方法

6.可以通过implements实现多个接口

7.要实现接口必须重写里面的方法

Demo01

package 接口;

public interface TimeService {

    void timer();
}

Demo02

package 接口;


//interface:接口
public interface UserService {

    //接口中的所有定义的方法其实都是抽象的,默认为public abstract
    public abstract void add(String name);
                    void delete(String name);
                    void update(String name);
                    void query(String name);

                    //接口都需要有实现类。

     //接口中的所有定义的属性其实都是常量,默认为public static final
    public static final int AGE = 99;

}

Demo03

package 接口;

//类可以通过implements实现接口
//实现了接口的类,就需要重写接口的方法
//这样就从侧面利用接口实现了多继承

public class UserServiceUmpl 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() {

    }
}

内部类

  • 内部类就是在一个类的内部再定义一个类,比如,A类中定义一个B类,那么B类相对A类来说就称为内部类,而A类相对B类来说就是外部类了。

  • 1.成员内部类

  • 2.静态内部类

  • 3.局部内部类

  • 4.匿名内部类

成员内部类可以无条件访问外部类的所有成员属性和成员方法(包括private成员和静态成员)。 不过要注意的是,当成员内部类拥有和外部类同名的成员变量或者方法时,会发生隐藏现象,即默认情况下访问的是成员内部类的成员。

如果要访问外部类的同名成员,需要以下面的形式进行访问:

外部类.this.成员变量

外部类.this.成员方法

Demo01

package 内部类;

import com.sun.xml.internal.bind.v2.model.core.ID;

import javax.sound.midi.Soundbank;

public class Outer {

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


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

        //内部类直接访问外部类的一些东西,获得外部类的一些私有属性
       public void getID(){
           System.out.println(id);

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

       }

    }
    //局部内部类:
    public void method(){

        class Inner{
            public void in(){

            }

        }
    }

}

//Outer测试类

/*
 public static void main(String[] args) {

        //通过new实现外部类的调用
        Outer outer = new Outer();

        //通过这个外部类来实例化内部类
        Outer.Inner inner = outer.new Inner();

        inner.in();

        inner.getID();

    }
 */

Demo02

package 内部类;

public class Test {

    //匿名内部类:
    public static void main(String[] args) {

        //有名字的初始化类
        Apple apple = new Apple();

        //没有名字的初始化类,不用将实例保存到变量中
        new Apple().eat();


        new UserService(){
            @Override
            public void hello() {

            }
        };

    }

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

interface UserService{
    void hello();
}
posted @ 2021-09-14 11:34  花朝十三博客  阅读(38)  评论(0)    收藏  举报