面向对象编程

1、初识面向对象

面向过程&面向对象

🔷面向过程思想

🔷步骤清晰简单,第一步做什么,第二步做什么.....

🔷面对过程适合处理一些较为简单的问题

🔷面向对象思想

🔷物以类聚,分类的思维模式,思考问题首先会解决问题需要哪些分类,然后对这些分类进行单独思考。

        最后,才对某个分类下的细节进行面向过程的思索。

🔷面向对象适合处理复杂的问题,适合处理需要多人协作的问题!

🔷对于描述复杂的事物,为了从宏观上把握、从整体上合理分析,我们需要使用面向对象的思路来分析整个系 统。但是,具体到微观操作,仍然需要面向过程的思路去处处理

什么是面向对象

🔷面向对象编程(Object-Oriented Programming, OOP)

🔷面向对象编程的本质就是:以类的方式组织代码,以对象的组织(封装)数据

🔷抽象

🔷三大特性:

        🍉封装

        🍉继承

        🍉多态

🔷从认识论角度考虑是先有对象后有类。对象,是具体的事物。类,是抽象的,是对对象的抽象

🔷从代码运行角度考虑是先有类后有对象。类是对象的模板。

2、方法回顾和加深

🔷方法的定义

        🍉修饰符

        🍉返回类型

        🍉break:跳出switch,结束循环 和return的区别

        🍉方法名:注意规范就OK 见名知意

        🍉参数列表:(参数类型,参数名)......

        🍉异常抛出:疑问,后面讲解

代码实例

public class Demo1 {

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

    }

    /*
      修饰符  返回值类型   方法名(){
        //方法体
        return 返回值;
    }
    */
    // 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{}
}

🔷方法的调用

        🍉静态方法

        🍉非静态方法

        🍉形参和实参

        🍉值传递和引用传递

        🍉this关键字 

public class Demo7 {
    public static void main(String[] args) {
        //  实际参数和形式参数的类型要对应
        int add = Demo7.add(1, 2);
        System.out.println(add);
    }

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

🔷值传递和引用传递

//值传递    java是值传递
public class Demo8 {
    public static void main(String[] args) {
        int a = 1;
        System.out.println(a);  //1

        Demo8.change(a);
        System.out.println(a);  //1
    }

    //返回值为空
    public static void change(int a){
        a = 10;
    }
}
//引用传递:一般传递对象,本质还是值传递
//听起来有点晕!没有了解对象!内存!
public class Demo9 {
    public static void main(String[] args) {
        Person person = new Person();
        System.out.println(person.name);  //null

        Demo9.change(person);
        System.out.println(person.name);  //冯宝宝
    }
    public static void change(Person person){
        //person是一个对象:指向的----> Person person = new Person();这是一个人,可以改变属性!
        person.name = "冯宝宝";
    }
}

//一个类里面只能有一个public class   但是可以有多个class
//定义了一个Person类,有一个属性name
class Person{
    String name;  //默认值null
}

3、对象的创建分析

💥万物皆对象

        世界是由什么组成的?

分类是人们认识世界的一个很自然的过程,在日常生活中会不自觉地进行分类

💥身边的对象

💥对象的特征—属性

🔷属性:对象具有的各种特征

🔷每个对象的每个属性都拥有特定值

        🍉例如:张浩和李明的年龄、姓名不一样

 

 

💥对象的特征—方法

🔷方法:对象执行的操作

💥对象的属性和方法

🔷列出尼古拉斯·凯奇驾驶的这辆法拉利F360 Spider的属性和方法

 

🔷列出小狗对象的属性和方法

💥封装

🔷对象同时具有属性和方法两项特性

🔷对象的属性和方法通常被封装在一起,共同体现事物的特性, 二者相辅相承,不能分割

💥小结

🔷说一说教室里的对象

🔷描述他们的属性和方法

💥从对象抽象出“类”

🔷抽取出下列对象的共同特征(属性和方法)

💥类

💥类和对象的关系

🔷类是一种抽象的数据类型,它是对某一类事物整体描述/定义,但是并不能代表某一个具体的事物.

        🍉动物、植物、手机、电脑......

        🍉Person类、Pet类、Car类等,这些类都是用来描述/定义某一类具体的事物应该具备的特点和行为

🔷对象是抽象概念的具体实例

        🍉张三就是人的一个具体实例,张三家里的旺财就是狗的一个具体实例。

        🍉能够体现出特点,展现出功能的是具体 的实例,而不是一个抽象的概念.

🔷类是抽象的概念,仅仅是模板

        比如说:“人”

🔷对象是一个你能够看得到、摸得着的具体实体

 

 

💥创建于初始化对象

🔷使用new关键字创建对象

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

💥Java类模板

🔷类将现实世界中的概念模拟到计算机程序中

💥定义类2-1

🔷定义一个类的步骤

💥类示例

🔷在不同学校,会感受到相同的环境和教学氛围,用类的思想输出中心信息

💥类示例2-2

💥如何创建和使用对象

💥面向对象(OO)的优点

代码实例

//学生类
public class Student {

    //属性:字段
    String name;  //null
    int age;      //0


    //方法   this:代表当前这个类
    public void study(){
        System.out.println(this.name+"在学习");
    }
}
// 一个项目应该只存在一个main方法
public class Application {
    public static void main(String[] args) {
        //类:抽象的,实例化   new       快捷键 :alt+enter回车
        //类实例化后悔返回一个自己的对象!
        //fbb对象就是一个Student类的具体实例!
        Student fbb = new Student();

        //赋值
        fbb.name="冯宝宝";
        fbb.age =18;
        //打印
        System.out.println(fbb.name);
        System.out.println(fbb.age);

        Student fjq = new Student();

        //赋值
        fjq.name="冯加奇";
        fjq.age =18;
        //打印
        System.out.println(fjq.name);
        System.out.println(fjq.age);

    }
}

💥构造器详解

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

        1.必须和类的名字相同

        ⒉必须没有返回类型,也不能写void

🔷构造器必须要掌握

一个类即使什么都不写,它也会存在一个方法,这就是构造器

代码实例

public class Person {
    //一个类即使什么都不写,它也会存在一个方法
    //显示的定义构造器
    String name;

    //无参构造的作用
    //实例化初始值
    //1,使用new关键字,本质还是调用构造器,断点调试
    //2,用来初始化值
    public Person(){
       // this.name = "冯宝宝";
    }

    //有参构造:一旦定义了有参构造,无参就必须显示定义,断点调试
    public Person(String name){
        this.name = name;
    }
    
    //alt+insert:快捷键,快速生成有参构造和无参构造
}
public class Application2 {
    public static void main(String[] args) {

        // new 实例化了一个对象
        Person person = new Person("冯宝宝");
        System.out.println(person.name);   //冯宝宝
    }
}

💥构造器总结:

        1.和类名相同

        2.没有返回值

作用:

        1. new本质在调用构造方法

        2.初始化对象的值

注意点:

        1. 定义有参构造之后,如果想使用无参构造,显示的定义一个无参的构造

        alt+insert:快捷键,快速生成有参构造和无参构造

        this:代表当前这个类

💥创建对象内存分析

代码实例

public class Pet {
   public String name;
   public int age;

    //无参构造

    public void shout(){
        System.out.println("叫了一声");
    }
}
public class Application {
    public static void main(String[] args) {
        Pet dog = new Pet();
        dog.name = "旺财";
        dog.age = 3;
        dog.shout();
        System.out.println(dog.name);
        System.out.println(dog.age);
    }
}

总结


1.类与对象

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

2.方法

        定义、调用!

3.对应的引用

        引用类型:基本类型(8)

        对象是通过引用来操作的:栈——>堆(地址)

4.属性:字段Field 成员变量

        默认初始化:

        数字:0 0.0

        char:u0000

        boolean:false

        引用:null

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

5.对象的创建和使用

        必须使用 new 关键字创建对象,构造器 Person fbb = new Person();

        对象的属性:fbb.name

        对象的方法:fbb.sleep();

6.类:

        静态的属性:属性

        动态的行为:方法


4、面向对象三大特性

❤️封装

        🔷该露的露,该藏的藏

                🍉我们程序设计要追求“高内聚,低耦合”。高内聚就是类的内部数据操作细节自己完成,

                🍉不允许外部干涉;低耦合:仅暴露少量的方法给外部使用。

        🔷封装(数据的隐藏)

                🍉通常,应禁止直接访问一个对象中数据的实际表示,而应通过操作接口来访问,这称为信息隐藏。

        🔷记住这句话就够了:属性私有,get/set

💥什么是封装(🌟🌟🌟🌟重点)

🔷面向对象三大特征之一 ——封装

        🍉封装的概念

                封装:将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问

💥封装的好处

💥如何使用封装

🔷封装的步骤

代码实例

 

/*
*   1.提高程序的安全性,保护数据
*   2.隐藏代码的实习细节
*   3.统一接口   get  set
*   4.系统可维护性增加了
*/
//学生类   // private:私有
public class Student {

    //属性私有化
    private String className;     //名字
    private int id;      //学号
    private char sex;   //性别
    private int age;    //年龄



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

    //get 获得这个数据
    public String getClassName(){
        return this.className;
    }

    //set  给这个数据设置值
    public void setClassName(String className){
        this.className = className;
    }

    // 快速生成get、set方法 快捷键  alt+insert
    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;
        }

    }
    //学习()
    //睡觉()
}
public class Application {
    public static void main(String[] args) {
        Student student = new Student();
        student.setClassName("冯宝宝");
        System.out.println(student.getClassName());

        student.setAge(999);  //不合法
        System.out.println(student.getAge());
    }
}

💥封装的好处

 

💥this的用法(🌟🌟🌟🌟重点)

🔷this关键字的用法

💫调用属性

💫调用方法

💫调用构造方法

💫如果使用,必须是构造方法中的第一条语句

public class Student {
    //属性私有化
    private String className;     //名字
    private int id;      //学号
    private char sex;   //性别
    private int age;    //年龄

    public Student() {
        //this("冯宝宝",8,'男',18);
        System.out.println(this);
    }

    public Student(String className, int id, char sex, int age) {
        //this();
        this.className = className;
        this.id = id;
        this.sex = sex;
        this.age = age;
    }
}

 💥总结


❤️继承

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

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

        🔷JAVA中类只有单继承,没有多继承!

                一个儿子只能有一个爸爸,但是一个爸爸可以有多个儿子

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

        🔷继承关系的俩个类,一个为子类(派生类),一个为父类(基类)。

                子类继承父类,使用关键字extends来表示。

        🔷子类和父类之间,从意义上讲应该具有"is a"的关系.

        🔷object类

        🔷super :重点

        🔷方法重写:重点

💥为什么使用继承

        🔷生活中的基础

💥如何使用继承

🔷使用继承

💠编写父类

💠编写子类,继承父类

代码实例

//在java中,所有的类,都默认直接或者间接继承object类
//人类:  父类
public class Person {
    //public : 公开的
    //protected: 受保护的(比默认的优先级高)
    //private: 私有的
    //default: 默认的
    private int money = 10_000_000;
    
    public int getMoney() {
        return money;
    }
    public void setMoney(int money) {
        this.money = money;
    }

    public void say(){
        System.out.println("说了一句话......");
    }
}
// 学生类 is 人:派生类,子类
// 子类继承了父类,就会拥有父类的全部方法!
public class Student extends Person{
    //Ctrl+H
}
public class Application {
    public static void main(String[] args) {
        Student student = new Student();
        student.say();
        System.out.println(student.getMoney());
    }
}

💥理解继承

 

🔷继承类型

        需要注意的是 Java 不支持多继承,但支持多重继承。

代码实例

//在java中,所有的类,都默认直接或者间接继承object类
//人类:  父类
public class Person {
    public Person() {
        System.out.println("Person无参执行了");
    }
    

    protected String name = "冯宝宝";

  //私有的东西无法被继承
  public void print(){
      System.out.println("Person");
  }
}
// 学生类 is 人:派生类,子类
// 子类继承了父类,就会拥有父类的全部方法!
public class Student extends Person{
    //Ctrl+H
    public Student() {
        //隐藏代码:调用了父类的无参构造
        super();//调用父类的构造器,必须要在子类构造器的第一行
        System.out.println("Student无参执行了");
    }

    private String name="马云";

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

    public void test1(){
        print();        //Student
        this.print();   //Student
        super.print();  //Person
    }

    public void test2(String name){
        System.out.println(name);//乐学优课
        System.out.println(this.name);//马云
        System.out.println(super.name);//冯宝宝
    }
}
public class Application {
    public static void main(String[] args) {
        Student student = new Student();
        student.test2("乐学优课");
        System.out.println("----------");
        student.test1();
    }
}

 

💥方法的重写(override)

🔷方法重写只存在于子类和父类(包括直接父类和间接父类)之间。

        在同一个类中方法只能被重载,不能被重写

🔷 静态方法不能重写

        💠父类的静态方法不能被子类重写为非静态方法 //编译出错

        💠父类的非静态方法不能被子类重写为静态方法;//编译出错

        💠子类可以定义与父类的静态方法同名的静态方法(但是这个不是覆盖)

代码实例

public class Application {
        //静态的方法和非静态的方法区别很大!
        //静态方法:方法的调用只和左边(定义的数据类型)有关
        //非静态:重写
    public static void main(String[] args) {

        //方法的调用只和左边(定义的数据类型)有关
        A a = new A();
        a.test();

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

    }
}
//继承
public class A extends B{

//    public static void test(){
//        System.out.println("A-->text()");
//    }

    //Override 重写
    @Override//注解:有功能的注释!
    public void test() {
        //super.test();//默认调用父类的test()
        System.out.println("A-->test()");
    }
}
//重写是方法的重写,与属性无关
public class B {
//    public static void test(){
//        System.out.println("B-->text()");
//    }

    public  void test(){
        System.out.println("B-->text()");
    }

}

 

💥抽象类

🔷abstract修饰符可以用来修饰方法也可以修饰类,如果修饰方法,

        那么该方法就是抽象方法;如果修饰类,那么该类就是抽象类。

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

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

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

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

代码实例

//abstract 抽象类  类:extends :单继承  ~  (接口可以多继承)插座~
public abstract class Action {

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

    //1.不能new 这个抽象类,只能靠子类去实现它;约束!
    //2.抽象类中可以写普通方法~
    //3.抽象方法必须在抽象类中~
    // 抽象的抽象:约束!

    public void show(){

    }

    //抽象类的意义: 把公共的抽象出来~  提高开发效率
    
}
public class A extends Action{

    @Override
    public void doSomething() {

    }
}
public class Application {
    public static void main(String[] args) {
        new Action();  //报错  不能实例化
    }
}

 

💥static

💦概述

        🍭static 关键字是静态的意思,是Java中的一个修饰符,可以修饰成员方法,成员变量

💦static修饰的特点

        🍭被类的所有对象共享是我们判断是否使用静态关键字的条件

        🍭随着类的加载而加载,优先于对象存在对象需要类被加载后,才能创建

        🍭可以通过类名调用也可以通过对象名调用

💦注意事项(理解)

        🍭静态方法只能访问静态的成员

        🍭非静态方法可以访问静态的成员,也可以访问非静态的成员

        🍭静态方法中是没有this关键字

代码实例

// static
public class Student {

    private static int age;  //静态的变量
    private double score;   //非静态的变量

    public void run(){
    }
    public static void go(){
    }
    public static void main(String[] args) {
        Student s = new Student();

        System.out.println(Student.age);
        System.out.println(s.score);
        System.out.println(s.age);

        s.run();
        go();
    }
}
public class Person {
    //2.和对象同时产生,作用:赋初始值
    {
        System.out.println("匿名代码块");
    }

    // 1.只执行一次 类的加载而加载
    static {
        System.out.println("静态代码块");
    }

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

    public static void main(String[] args) {
        new Person();
        System.out.println("----------------");
        new Person();
    }
}
package com.lxyk.oop6;
import static java.lang.Math.*;//静态导入包

/**
 * @ClassName Test
 * @Description TODO
 * @Author FJQ
 * @Date 2022/5/27 14:43
 * @Version 1.0
 **/
public class Test {

    public static void main(String[] args) {
      /*  System.out.println(Math.random());
        System.out.println(Math.PI);*/

        System.out.println(random());
        System.out.println(PI);
    }
}

💥final关键字

👍fianl关键字的作用

        💦final代表最终的意思,可以修饰成员方法,成员变量,类

👍final修饰类、方法、变量的效果

        💦fianl修饰类:该类不能被继承(不能有子类,但是可以有父类)

        💦final修饰方法:该方法不能被重写

        💦final修饰变量:表明该变量是一个常量,不能再次赋值

                🍭变量是基本类型,不能改变的是值

                🍭变量是引用类型,不能改变的是地址值,但地址里面的内容是可以改变的

代码实例

public class Action extends Student {
    
}
public final class Student {
}

💥代码块

💠在Java中,使用 { } 括起来的代码被称为代码块

  • 局部代码块

💠代码块的优先级

        静态代码块>构造代码块>构造方法;

public class Person {
    static{
        System.out.println("1.我是静态块,优先于构造块执行!并且只有创建第一个对象的时候执行一次!");
    }

    {
        System.out.println("2.我是构造块,优先于构造方法执行!每创建一个对象执行一次!");
    }

    public Person() {
        System.out.println("3.我是构造方法,每创建一个对象执行一次");
    }

    public void function1(){
        System.out.println("我是非静态方法中的普通代码块,方法被调用时执行!");
    }

    public static void function2(){
        System.out.println("我是静态方法中的普通代码块,方法被调用时执行,晚于静态块执行!");
    }
}
public class HelloWrold {
    public static void main(String[] args) {
        new Person().function1();
        new Person().function2();

        /*
        * 我们可以看出:静态块总是最先执行的,并且只有在创建该类的第一个实例的时候才会执行一次;
        * 第二执行的是构造块;第三执行的是构造方法。
        * */
    }
}

💥总结

非私有的成员方法和成员变量;
   b、子类不能继承父类的构造方法,但是可以通过super关键字去访问父类的       构造方法
   c、不要为了部分功能而去继承

1、this关键字和super关键字分别代表什么,以及他们各自的作用分别是什么?
   	this 关键字表示对象的引用,哪个对象来调用该类成员,就代表哪个对象
   	super 代表当前对象的父类的引用。

2、代码块是什么,分为哪几类,各自有什么特点?
   代码块是用{}括起来的语句;
   分类:根据位置和声明的不同分为以下几块:
   1)局部代码块:在方法中出现,限定变量生命周期,及早释放,提高内存利用率;
   2)构造代码块:又叫初始化块,
      在类中方法外出现,多个构造方法中相同的代码存放到一起,每次调用构造方法都执行,
并且在构造方法前执行。
   3)静态代码块:
      * 在类中方法外出现,并加上static修饰符,用于给类进行初始化,在类加载的时候就执行,并且只执行一次;
       一般用于加载驱动

   4)同步代码块:
 构造代码块,优先于构造方法执行,主要是为了提取构造方法中必须执行的公共代码!
构造代码块,每次创建对象时,都优先于构造方法执行!
作用:给构造方法进行初始化!
   		 被static修饰的,随着类的加载而加载,静态代码块  随着类的加载而执行
   		 静态代码块只执行一次
    		作用:用来加载特殊数据     比如:如果有些代码必须在项目启动的时候就执行,
需要使用静态代码块。

        静态代码块,在虚拟机加载类的时候就会加载执行,而且只执行一次;
        非静态代码块,在创建对象的时候(即new一个对象的时候)执行,
每次创建对象都会执行一次

        相同点:都是在JVM加载类时且在构造方法执行之前执行,在类中都可以定义多个,
     一般在代码块中对一些static变量进行赋值。
        不同点:静态代码块在非静态代码块之前执行(静态代码块—>非静态代码块—>构造方法)。
     静态代码块只在第一次类加载时执行一次,之后不再执行,而非静态代码块在每new
     一次就执行一次。非静态代码块可在普通方法中定义(不过作用不大);而静态代码块不行。
    
        总结:
        局部代码块:在方法中出现
        构造代码块:在类中方法外出现,随着对象的创建而加载,创建一次对象构造代码块执行一次
        静态代码块:随着类的加载而加载,并且只执行一次(一般用于加载驱动)
        主方法类中的静态代码块:优先于主方法执行
   
3、子父类都有静态代码块、构造代码块、构造方法,那么他们六者之间的执行流程是什么?
    父类静态代码块
    子类静态代码块
    父类构造代码块
    父类构造方法
    子类构造代码块
    子类构造方法

4、继承的好处、弊端分别是什么?
    好处:提高代码的复用性
          提高代码的维护性
          让类与类之间产生关系,是多态的前提
    弊端:类的耦合性增强了;
          开发的原则是:高内聚,低耦合

          耦合是类与类的关系
          内聚是自己完成某件事的能力

5、Java中继承的特点是什么?
   1)java中只支持单继承,不支持多继承(一个儿子只有一个亲爹)
   2)java中支持"多层"继承,也就是继承体系。

6、Java中继承的注意事项是什么?我们什么时候使用继承?
   a、子类只能继承父类所有
   this 的作用:
        1、this.成员变量:调用本类的成员变量,也可以调用父类的成员变量
        2、this(...) 调用本类的构造方法;
        3、this.成员方法:调用本类的成员方法,也可以调用父类的成员方法
    super 的作用
        1、super.成员变量:调用父类的成员变量
        2、super(...) 调用父类的构造方法;
        3、super.成员方法:调用父类的成员方法。

7、继承中构造方法的执行流程是什么?
     先访问父类的构造方法,再访问子类的构造方法;

8、为什么子类中所有的构造方法默认都会访问父类的空参构造?
   假如父类没有无参构造方法,子类应该怎么办?
   1、因为子类继承父类中的数据,也可能会使用父类的数据;
   2、子类初始化前,必须要要先将父类初始化。
   	如果父类没有空参构造,就用this或者super来调用父类的有参构造。

9、super关键字和this关键字可以在构造方法中共存吗?
  this()或者super()都必须是在构造方法中的第一行;

❤️多态

🔷动态编译:类型:可扩展性(多态可以让可扩展性更强)

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

🔷一个对象的实际类型是确定的,但可以指向对象的引用的类型有很多(父类,有关系的类)

🔷多态存在的条件

        💠有继承关系

        💠子类重写父类

        💠父类引用指向子类对象

🔷注意:多态是方法的多态,属性没有多态性。

🔷instanceof (类型转换)引用类型~

💥什么是多态

🔷生活中的多态

💠不同类型的打印机打印效果不同

🔷程序中的多态

 

💥如何实现多态

代码实例

public class Person {

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

    public void eat() {
        System.out.println("eat");
    }
}
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.run();   //子类重写了父类的方法,执行子类的方法
        s1.run();
        //对象能执行哪些方法,主要看对象左边的类型,和右边关系不大!
        s1.eat();
        //((Student) s2).eat();

        /*
            多态注意事项
            1.多态的方法的多态,属性没有多态
            2.父类和子类,有联系
            3.多态的前提,要有继承关系,要有方法重写,要有父类引用指向子类对象!

        */

    }
}

💥多态中的成员访问特点

🔷成员访问特点

        成员变量 编译看父类,运行看父类

        成员方法 编译看父类,运行看子类

代码实例

public class Fu {
    int num = 10;  // 成员变量

    //成员方法
    public void method(){
        System.out.println("Fu.. method");
    }
}
public class Zi extends Fu{
    int num = 20;

    public void method(){
        System.out.println("Zi.. method");
    }
}
public class Test {
    /*
       多态的成员访问特点:
              成员变量: 编译看左边 (父类), 运行看左边 (父类)
              成员方法: 编译看左边 (父类), 运行看右边 (子类)
   */
    public static void main(String[] args) {
        Fu f = new Zi();
        System.out.println(f.num);
        f.method();
    }
}

💥instanceof

🔷如果被转的引用类型变量,对应的实际类型和目标类型不是同一种类型,

        那么在转换的时候就会出现 ClassCastException

🔷解决方案

        关键字instanceof

        使用格式变量名 instanceof 类型

        instanceof 是 Java 的一个二元操作符,类似于 ==,>,< 等操作符。

        instanceof 是 Java 的保留关键字。它的作用是测试它左边的对象是否是它右边的类的实例,

        返回 boolean 的数据类型。

        通俗的理解:判断关键字左边的变量,是否是右边的类型,返回boolean类型结果

代码实例

public class Person {
    public void run(){
        System.out.println("run");
    }
}
public class Student extends Person{
}
public class Teacher extends Person{
}
public class Action {
    public static void main(String[] args) {

        // Object > String
        // Object > Person > Teacher
        // Object > Person > Student
        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);   // false   //编译就报错
        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);  // false  //编译就报错
        //System.out.println(person instanceof String);   // false   //编译就报错

        //System.out.println(X instanceof Y);  //能不能编译通过 !  看x和y有没有父子关系
    }
}

💥多态中的转型

🔷向上转型

        父类引用指向子类对象就是向上转型

🔷向下转型

        格式:子类型 对象名 = (子类型)父类引用;

代码实例

class Fu {
    public void show(){
        System.out.println("Fu..show...");
    }
}

class Zi extends Fu {
    @Override
    public void show() {
        System.out.println("Zi..show...");
    }

    public void method(){
        System.out.println("我是子类特有的方法, method");
    }
}

public class Test3Polymorpic {
    public static void main(String[] args) {
        // 1. 向上转型 : 父类引用指向子类对象
        Fu f = new Zi();
        f.show();
        // 多态的弊端: 不能调用子类特有的成员
        // f.method();

        // A: 直接创建子类对象
        // B: 向下转型

        // 2. 向下转型 : 从父类类型, 转换回子类类型
        Zi z = (Zi) f;
        z.method();
    }
}

 

5、接口

🔷普通类:只有具体实现

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

🔷接口:只有规范!

🔷接口就是规范,定义的是一组规则,体现了现实世界中“如果你是...则必须能...”的思想。

        如果你是天使,则必须能飞。如果你是汽车,则必须能跑。如果你好人,则必须干掉坏人;

        如果你是坏人,则必须欺负好人。

🔷接口的本质是契约,就像我们人间的法律一样。制定好后大家都遵守。

🔷OO的精髓,是对对象的抽象,最能体现这一点的就是接口。

        为什么我们讨论设计模式都只针对具备了抽象能力的语言(比如c++、java、c#等),

        就是因为设计模式所研究的,实际上就是如何合理的去抽象。

使用接口设计

防盗门功能


💥目标

  • 掌握接口基础知识
  • 掌握接口作为一种约定和能力的含义(重点,难点)
  • 掌握面向接口编程(重点,难点)

💥为什么使用接口

        问题?

        我现在的需求是:要用java求实现防盗门的功能

分析:

        门有“开”和“关”的功能,锁有“上锁”和“开锁”的功能,将门和锁分别定义为抽象类

思路:

        将门定义为抽象类,锁定义为接口

        防盗门继承门,实现锁的接口

        防盗门可以继承门的同时又继承锁吗?

如何解决这个问题呢?

        那我们java有没有什么办法和技术点解决这个问题嘛?

        当然有,那就是我们今天要学习的新知识点,接口

💥什么是接口

语法

🔷1.认识一下接口

🔷2.接口的特性

        接口不可以被实例化

        实现类必须实现接口的所有方法

        实现类可以实现多个接口

        接口中的变量都是静态常量 :public static final

        接口中所有的方法必须是抽象方法:public abstract

        Java 8 之后 接口中可以使用 default 关键字修饰的非抽象方法。

💥如何使用接口

用程序描述USB接口

分析

        USB接口本身没有实现任何功能

        USB接口规定了数据传输的要求

        USB接口可以被多种USB设备实现

可以使用Java接口来实现

编码实现

注意:(接口是java的多继承)

💥接口表示一种能力

做这项工作需要一个钳工(木匠/程序员)

接口是一种能力

面向接口编程

💥面向接口编程3-1

问题

实现防盗门功能

分析

 

💥面向接口编程3-2

实现过程

💥上代码(案列)

门:Door(抽象类)

public abstract class Door {
    public abstract void open();  //开
    public abstract void close(); //关
}

防盗门: TheftproofDoor(类)

public class TheftproofDoor extends Door implements Lock {
​
    @Override
    public void lockUp() {
        System.out.println("插进钥匙,向左旋转钥匙三圈,锁上了,拔出钥匙。");
    }
​
    @Override
    public void openLock() {
        System.out.println("插进钥匙,向右旋转钥匙三圈,锁打开了,拔出钥匙。");
​
    }
​
    @Override
    public void open() {
        System.out.println("用力推,门打开了。");
    }
​
    @Override
    public void close() {
        System.out.println("轻轻拉门,门关上了。");
    }
}

测试类:DoorTest

public class DoorTest {
    public static void main(String[] args) {
        //创建具体防盗对象
        TheftproofDoor tfd = new TheftproofDoor();
        tfd.close();  //关门
        tfd.lockUp(); //锁门
        tfd.openLock(); //开锁
        tfd.open();  //开门
    }
}

💥面向接口编程3-3

问题

扩展防盗门门铃功能,主要是实现拍照存档

 

 

💥学员操作:使用接口实现防盗门功能

需求说明:

使用面向接口编程实现防盗门的功能

        💫开门、关门

        💫上锁、开锁

        💫拍照存档

防盗门实现门铃接口即可

测试类调用方法:takePictures();

💥小结

如何理解接口是一种能力?

代码实例

// 抽象的思维~java
// interface:定义的关键字, 接口都需要有实现类
public interface UserService {
    //静态常量~  一般不会在接口定义常量,只会定义方法
    public static final int AGE = 99;


    // 接口中的所有定义的方法   其实都是抽象的  public abstract
    public abstract void add(String name);
    void delete(String name);
    void update(String name);
    void query(String name);
}
public interface TimeService {
    void timer();
}
// 抽象类:extends~
// 类  可以实现接口    implements  接口
// 实现了接口的类,就需要重写接口中的方法~

// 多继承~利用接口实现多继承~
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() {

    }
}

💥抽象类vs接口

 

💥面向对象设计原则

高耦合,低内聚

多用组合,少用继承针对接口编程针对扩展开放,针对改变关闭

 阅读代码,找出错误

public interface MyInterface {       
       public MyInterface();         错
       public void method1();        对
       public void method2(){ }      错
       private void method3();       错
       void method4();              对
       int method5();               对
       int TYPE = 1;                对
}

💥总结

 

 

6、内部类

💥内部类

🔷内部类就是在一个类的内部在定义一个类,比如,A类中定义一个B类,

        那么B类相对A类来说就称为内部类,而A类相对B类来说就是外部类了。

🔷1.成员内部类

        代码实例

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);
        }
    }

}
public class Action {
    public static void main(String[] args) {
        Outer outer = new Outer();
        //通过这个外部类来实例化内部类
        Outer.Inner inner = outer.new Inner();
        inner.in();
        inner.getID();
    }
}

🔷2.静态内部类

🔷3.局部内部类

  代码实例

public class Outer {

    //局部内部类(不建议这样玩)
    public void method(){
        class Inner{
            public void run(){
                System.out.println("局部内部类...");
            }

        }
        Inner inner = new Inner();
        inner.run();
    }


}

//一个Java类中可以有多个class 类,但是只能有一个public class
class A{
    public static void main(String[] args) {
        Outer outer = new Outer();
        outer.method();
    }
}

🔷4.匿名内部类

public class Test {
    public static void main(String[] args) {
        //没有名字初始化类,不用将实例保存到变量中!
        new Apple().eat();
        new UserService(){
            @Override
            public void hello() {

            }
        };
        
    }
}

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

interface UserService{
    void hello();
}

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值