Day_06 Java的面向对象

文章详细讲解了Java中的面向对象特性,包括类与对象的概念,如何创建与初始化对象,以及构造器的作用。还介绍了方法的定义与调用,值传递与引用传递的区别,并探讨了封装、继承和多态等核心概念,如方法重写、静态与非静态方法、抽象类与接口等。
摘要由CSDN通过智能技术生成

1.什么是面向对象

System.out.println()  // 类.对象.方法

在这里插入图片描述

在这里插入图片描述

2.方法的加深与回顾

2.1 方法的定义

//demo01是一个类  ,里面有一个main方法
/*方法的定义
修饰符   返回值类型   方法名(...){
	方法体;
    返回值
      }
*/
public class demo01 {
    //main方法
    public static void main(String[] args) {
    }
    //定义简单的方法
    public String sayHello()
    {
        return "Hello World";
    }
    public int max(int a,int b)
    {
        return a > b ? a : b ;//三元运算符
    }
}

2.2 方法的调用

  • 方法的调用有静态方法 ( s t a t i c ) 、非静态调方法 \textcolor{red}{方法的调用有 静态方法(static)、非静态调方法} 方法的调用有静态方法(static)、非静态调方法
  • 也有调用写在自身类里面的方法,或者调用写在其它类里面的方法(简单的,就是用静态与非静态的方法) \textcolor{red}{也有调用写在自身类里面的方法,或者调用写在其它类里面的方法(简单的,就是用静态与非静态的方法)} 也有调用写在自身类里面的方法,或者调用写在其它类里面的方法(简单的,就是用静态与非静态的方法)

2.2.0 写在其它类里的方法

//student类
//静态方法 static//非静态方法
public class Student {
    //静态方法
    public static void say1(){
        System.out.println("学生说话了");
    }

    //非静态方法
    public void say2(){
        System.out.println("学生说话了");
    }

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

2.2.1 静态方法调用(static)

//方法调用的方法
public class demo02 {
    //类中只有属性和方法
    //在student类中写的代码,要在另一类中调用
    public static void main(String[] args) {
        //静态调用 , 类名.方法
        Student.say1();//写在其它类里,调用2.2.0的Student类
        
        demo02.c();//写在自己类里的可以 类.方法  。或者直接用c()
    }

    //方法的另一种,有两非静态方法a可以直接调用b
    public void a(){
        b();
    }
    public void b(){

    }

    //方法的另一种,有两静态方法a可以直接调用b
    public static void c(){
        d();
    }
    public static void d(){

    }

    //方法的另一种,有一个静态、还有一个非静态。无法直接调用
    //运行时public static和类一起加载
//    public static void e(){
//        f();
//    }
//    //public 类实例化之后才存在
//    public void f(){
//
//    }


}

2.2.2 非静态方法的调用

public class demo02 {
    //在student类中写的代码,要在另一类中调用
    public static void main(String[] args) {
        //非静态调用,要把类实例化 ,new。实例化就是new出一个对象
        //对象类型 对象名  = 对象值
        Student student = new Student();
        student.say2();
        //或者new Student().say2();无参数,无法补全,直接用就行了

        //如果有参数
        Student student1 = new Student();
        int added = student1.add(5, 3);
        /*或者 new Student().add(5,3)+alt+enter补全
        变成int added1 = new Student().add(5, 3);*/
    }
}

2.3 值传递与引用传递

  • 值传递:就是类似于c语言的形参与实参
public class demo04 {
    public static void main(String[] args) {
        //值传递相当于c语言的形式参数,与实际参数
        int a=1;
        System.out.println(a);//输出:1
        demo04.change(a);
        System.out.println(a);//输出:1
    }

    public static  void change(int a)
    {
        a=10;
    }
}
  • 引用传递:new出一个对象(这个new出来的名字是一个引用变量名)。引用变量名在栈里,指向在堆里的对象
//引用传递
public class demo05 {
    public static void main(String[] args) {
        //使用Person类
        Person person = new Person();//new出一个Person对象,并且把引用值(地址)返回给person
        System.out.println(person.name);//输出为:null
        System.out.println(person.age);//输出为:0

        demo05.change(person);
        System.out.println(person.name);//输出为:luchao 
        System.out.println(person.age);//输出为:1
    }

    public static void change(Person a)//Person类对象 a
    {
        //a是一个对象,指向的是--->Person a = new Person();
        //对象差不多类似于c语言的指针(地址),可以直接对其修改
        a.name = "luchao ";
        a.age=1;
    }
}
//一个类里面智能有一个public class 。但能有多个class
//定义了一个Person类,有两个属性 name 与 age
class Person{
    String name;
    int age;
}

3.类与对象的创建

  • 类:是抽象的,是对某一类事物的整体描述/定义,类是一个模板
  • 对象:是类的具体实例。可以通过new出来

3.1创建与初始化对象

在这里插入图片描述

====================================================================================================

java书上p67页讲的好**

对类的实例化分为两步:(实例化就是创建对象,为对象分配存储空间,并同时对对象进行初始化。初始化用构造器) \textcolor{red}{对类的实例化分为两步:(实例化就是创建对象,为对象分配存储空间,并同时对对象进行初始化。初始化用构造器)} 对类的实例化分为两步:(实例化就是创建对象,为对象分配存储空间,并同时对对象进行初始化。初始化用构造器)

  1. 声明该类型的变量,这个变量没有定义一个对象。它只是能够引用对象的简单变量。(该变量存在栈里)
Jstudent s;  //声明一个Jstudent的变量s,s此时的值为null,没有引用任何对象

2.通过new创建一个对象。通过new运算符,创建一个对象的实际的物理拷贝,并且把该对象的引用值(地址)赋给变量s。

​ new运算符为对象在分配内存空间(在堆里分配),并且返回对象的引用值(系统分配给对象的内存地址)。由于类是一种引用数据类型,因此变量s中存的不是对象本身,而是对象的引用值(地址)。

s= new Jstudent();//通过new实例化对象,把引用值(对象的地址)给s。此时s指向对象,通过s可以得到对象

在这里插入图片描述

=========================================================================================================

例子:

创建一个学生 S t u d e n t 类 \textcolor{red}{创建一个学生Student类} 创建一个学生Student

//学生类
public class Student {
    //属性:就是字段。或者说是变量。
    String name;
    int age;

    //方法
    public void study()
    {
        //this代表当前的类
        System.out.println(this.name+"在学习");
    }

}
//面向对象本质:以类的方式组织代码,以对象的形式封装数据

创建另一个类,这类里面有 m a i n 。对 S t u d e n t 类进行引用 \textcolor{red}{创建另一个类,这类里面有main。对Student类进行引用} 创建另一个类,这类里面有main。对Student类进行引用

//一个项目只存在一个main方法。这个main卸载另一个类里面
public class Application {
    public static void main(String[] args) {
        //我们要引用学生类。
        //由于类是抽象的,要把类实例化new后会返回一个自己的对象
        Student xiao_ming = new Student();//学生类实例化成对象小明
        Student xiao_hong = new Student();//学生类实例化成对象小红
        //对实例化的对象初始化
        xiao_ming.name = "小明";
        xiao_ming.age = 16;
        xiao_hong.name = "小红";
        xiao_hong.age = 20;
        System.out.println(xiao_ming.name);
        System.out.println(xiao_hong.name);
        System.out.println(xiao_ming.age);
        System.out.println(xiao_hong.age);
    }
}
//面向对象本质:以类的方式组织代码,以对象的形式封装数据

3.2创建对象的内存分析(狂神图,这个图也可以理解)

public class Pet {//创建一个宠物类
    public String name;//在不同的包里要加public
    public int age;

    public void shout()
    {
        System.out.println("叫了一声");
    }
}

import com.oop.Demo03.Pet;
public class Application {
    public static void main(String[] args) {
        Pet dog = new Pet();//类的实例化
        dog.name="wang_cai";
        dog.age = 3;
        dog.shout();

        Pet cat = new Pet();
    }
}

在这里插入图片描述

3.3 构造器

构造器含义:构造器也叫做构造方法,是进行创建对象new必须调用的。
构造方法特点:1.必须和类的名字相同
			2.必须没有返回类型,不能写void
			3.创建类里面,已经有默认的无参构造器。可以再main中直接new出来

构造器的作用:1使用new关键字必须要有构造器,new的本质是在调用构造器
			2.构造器可以初始化对象的值
    
注意点:	1.定义有参构造智慧化,如果使用无参构造,必须显示定义一个无参构造
			2.快捷键:alt+fn+insert快捷生成构造器

例子:

创建一个人 P e r s o n 类 \textcolor{red}{创建一个人Person类} 创建一个人Person

//构造器
public class Person {
    /*一个类即使什么都不写,也存在一个方法(也就是构造方法),这是默认的
    存在的构造方法是:public Person(){}
    * */
    /*
    构造器含义:构造器也叫做构造方法,是进行创建对象new必须调用的。
    构造方法特点:1.必须和类的名字相同
                2.必须没有返回类型,不能写void
                3.创建类里面,已经有默认的无参构造器。可以再main中直接new出来
    构造器的作用: 1.使用new关键字必须要有构造器,new的本质是在调用构造器
                2.构造器可以初始化对象的值
   注意点:1.定义有参构造智慧化,如果使用无参构造,必须显示定义一个无参构造
         2.快捷键:alt+fn+insert快捷生成构造器

     */

    String name;
    //显示定义无参构造器.构造器可以实例化初始值
    public Person()
    {
        this.name="luchao";//也可以什么都不写
    }

    //显示定义有参构造器.构造器可以实例化初始值。
    //如果有有参构造,必须显示定义一个无参构造。 一般无参构造是默认的有的,但是有了有参构造必须说明。
    public Person(String name)
    {
        this.name = name;
    }


}

创建一个人 m a i n 运行 \textcolor{red}{创建一个人main运行} 创建一个人main运行

//一个项目只存在一个main方法
public class Application {
    public static void main(String[] args) {
        //Person里面什么都没有,也能通过new实例化一个对象
        Person person1 = new Person();//无参构造器
        System.out.println(person1.name);//输出:luchao

        Person person2 = new Person("wdsadsa");//有参构造器
        System.out.println(person2.name);//输出:wdsadsa
    }

4.面向对象三大特性(封装、继承、多态)

4.1封装

在这里插入图片描述

例子:

创建一个人 S t u d e n t 类 \textcolor{red}{创建一个人Student类} 创建一个人Student

//封装:封装大部分是对于属性(变量)来的,不对于方法
public class Student {
    //private 属性私有 ,无法像public一样被调用
    public String name1;//public 可以随意调用
    private  String name2;//名字
    private  int id;//学号
    private  char sex;//性别
    private int age;

    //提供一些可以操作私人属性的方法
    //提供一些public的get 与 set 的方法.用公共方法操作私人属性。
    //get获得这个数据
    public String getName2()
    {
        return this.name2;
    }

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

    //快捷键 alt+fn+insert
    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        if(age>120 || age <0)//不合法的相关处理操作
        {
            this.age=3;

        }
        else
        {
            this.age = age;
        }
    }
}

创建一个 m a i n 运行 \textcolor{red}{创建一个main运行} 创建一个main运行

import com.oop.Demo04.Student;

public class Application {
    public static void main(String[] args) {
        Student s1 = new Student();
        s1.name1 = "a";//public随意调用
        //用public的get与set等公共方法来对私人属性操作。
        s1.setName2("lucaho");
        String n = s1.getName2();
        System.out.println(n);


        s1.setAge(999);//年龄999,不合法的。可以再方法中进行判定
        System.out.println(s1.getAge());//当不合法时候,会进行修改。修改成3

    }
}

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

4.2 继承

在这里插入图片描述

4.2.1 继承的用法与Object类

例子:

创建一个 P e r s o n 父类 \textcolor{red}{创建一个Person父类} 创建一个Person父类

//继承
//另外final 常量。只有方法才能被重写。  final也可以修饰类 public final class Person 修饰类不可以被继承
//Person 人 父类
//在子类中extends用于继承父类
//快捷键 ctral+H打开树,可以看到各种继承关系。并且会有一个Object类
//在java中所有的类都默认直接或者间接继承Object类
//父类与子类都继承Object,都可以调用相应的Object方法
//子类只能有一个父类,父类可以有多个子类
public class Person {
    //public 最高级。子类继承父类方法用public
    //protected 受保护
    //default 默认 int age
    //private 私人,用于父类的属性
    
    private int money =10_000;//继承中,属性基本上是private
    public int a=10;//继承中,属性也可以是public共有的
    public void say()
    {
        System.out.println("说了一句话");
    }

	//对private属性进行修改
    public int getMoney() {
        return money;
    }

    public void setMoney(int money) {
        this.money = money;
    }
}

创建一个 T e a c h e r 子类与 S t u d e n t 子类 \textcolor{red}{创建一个Teacher子类与Student子类} 创建一个Teacher子类与Student子类

//学生 is 人 子类、派生类
//子类继承父类,就会拥有父类的全部方法、属性(除了私有的之外)

public class Student extends Person{//学生继承了人
    //子类继承父类的方法
    //父类中有say,子类中没写也可以调用
    //子类也继承了Object祖父中的方法、属性。

}
//Teacher 也是人  。子类、派生类
public class Teacher extends Person{
}

创建一个 m a i n 类运行 \textcolor{red}{创建一个main类运行} 创建一个main类运行

public class Application {
    public static void main(String[] args) {
        Student student = new Student();
		student.say();//子类继承父类的方法、属性(父类属性是私有的,父类的属性也可以公有public)。父类中有say,子类中没写也可以调用
        
        //子类继承父类的private属性,并进行相应的修改
		student.setMoney(10);     
		System.out.println(student.getMoney());
        
        //子类继承父类的public
        int aa = student.a;


    }
}

4.2.2 this与super

super注意点:
    super可以在子类中调用父类的方法、构造方法和属性。(属性如果是private不能调用,其它的都可以调用)
    1.super调用父类的构造方法,在构造方法中必须是第一个。
    2.super必须只能出现在子类的方法、构造方法之中
    3.在子类的构造方法中,supper与this不能同时出现
    4.子类的构造会无条件调用父类的构造,因为子类的构造中有默认的supper。
    5.可以不用写子类的无参构造,如果写了也没事。在子类的无参构造中,是默认有隐藏的supper(),调用父类的无参构造,也可以把supper()明写出来。
    6.如果父类中只有有参构造,没有无参构造,就需要明写supper(相应参数);(建议在父类中写的时候,父类的有参构造和无参构造都写)

superthis相比较:
    1.this关键字用于访问当前对象,可以用来引用当前对象的属性和方法。this在没有继承也可以使用。
      (this相当于是一个对象,不用new的本身就有,是本类中的对象。this可以调用与修改**本类**的一些属性、方法)
      super关键字用于访问父类对象,可以用来调用父类的构造方法、成员方法和属性。只能在继承条件下使用

    2.this()在构造方法中默认调用本类的构造。supper()在子类的构造方法中默认调用父类的构造。

例子:

创建一个 P e r s o n 父类 \textcolor{red}{创建一个Person父类} 创建一个Person父类

public class Person {

    public Person() {//无参构造器
        System.out.println("Person无参构造器被执行了");
    }
    
    public Person(String name ) {//有参构造器。写了有参必须加无参
        System.out.println(name+":Person有参构造器被执行了");
    }


    public  String name= "luchao";//或者 protected String name= "luchao".。两种表示都可以被子类调用
    public void print()
    {
        System.out.println("person");
    }

    //私有的东西没法被继承
    private void s()
    {
    }
}

创建一个 S t u d e n t 子类 \textcolor{red}{创建一个Student子类} 创建一个Student子类

public class Student extends Person {

    public Student() {
        //隐藏代码:默认调用了父类的无参构造super();
        super();//可以不写,把super()显示出来。调用父类的构造器必须的放在子类构造器第一行
        System.out.println("子类的无参构造被执行了");
    }
    //加入父类中无参构造没了,只有有参构造。子类无法直接调用父类的有参构造,需要加上supper(相应的参数)

    private String name = "yanzhiyouxi";
    public int ass=3;

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

    public void a()
    {
        this.ass=4;
        System.out.println(this.ass);//this可以对本类中的属性进行修改
    }


    public void test1(String name)//this与super属性的调用
    {
        this.a();
        System.out.println(name);//输出形参name
        System.out.println(this.name);//使用this访问本类中的name
        System.out.println(super.name);//使用super访问父类的name
    }

    public void test2()//this与super方法的调用
    {
        print();//输出本类中的方法
        this.print();//和上一行一样效果,推荐用这个
        super.print();//父类方法的调用
    }

    public void test3()
    {
        //super.s();//父类中有private权限被锁
        //父类私有的东西没法被继承,无法用super调用
    }
}

创建一个 m a i n 类运行 \textcolor{red}{创建一个main类运行} 创建一个main类运行

public class Application {
    public static void main(String[] args) {
        Student student = new Student();//输出父类与子类的无参构造
        student.a();
        System.out.println();
        student.test1("陆超");//输出: 陆超  yanzhiyouxi   luchao
        student.test2();//输出: Student Student person
    }
}

4.2.2 方法重写

/*重写:子类与父类的方法名必须一致,方法体不同。
    前提:1.需要有子父的继承关系。
         2.方法名相同,方法体不同。
         3.必须是非静态的。
    含义:子类重写父类的方法
    快捷键 : alt+fn+insert  然后选中override;
    特点:
        1.方法名必须相同
        2.参数列表必须相同
        3.修饰符:范围可以扩大,但不能缩小。 修饰符的范围pulic> protected > default>private(注意:有private无法重写)
        4.抛出的异常:范围可以被缩小,但不能扩大。

    为什么需要重写?
        父类的功能子类不一定需要,或者不满足
    
不能被重写:1.static方法,属于类,不属于实例
          2.final 常量。只有方法才能被重写。  final也可以修饰类 public final class Person 修饰类不可以被继承
          3.private 无法继承,所以无法被重写
        */

例子:

创建一个 B 父类 \textcolor{red}{创建一个B父类} 创建一个B父类

public class B {

    public static void test()//有静态的不是重写
    {
        System.out.println("B=>test()");
    }

    public void test1()//子类与父类方法名相同,并且是非静态的,才能重写
    {
        System.out.println("B=>test()");
    }
}

创建一个 A 子类 \textcolor{red}{创建一个A子类} 创建一个A子类

public class A extends B{
    public static void test()//有静态的不是重写
    {
        System.out.println("A=>test()");
    }

    //写载快捷键alt+fn+insert。@Override这个注解是自动生成的
    @Override//注解:有功能的注释
    public void test1() {//子类与父类方法名相同,并且是非静态的,才能重写
        System.out.println("A=>test()");
    }
}

创建一个 m a i n 类运行 \textcolor{red}{创建一个main类运行} 创建一个main类运行

public class Application {
    public static void main(String[] args) {
        //父类子类方法都是static静态方法:方法的调用只和左边,定义的数据类型有关
        //重写方法与静态毫无关系,只与非静态有关系
        A a = new A();
        a.test();//输出:A=>test()
        //父类的引用B指向了子类A
        B b = new A();
        b.test();//输出:B=>test()


        //重写必须是非静态方法,并且必须是public
        //父类、子类方法不是static,是非静态方法。
        A c = new A();
        c.test1();//输出:A=>test()

        B d = new A();//子类重写了父类的方法
        d.test1();//输出A=>test()。子类重写了父类
    }
}

4.3多态

在这里插入图片描述

4.3.1多态的使用

例子:

创建一个 P e r s o n 父类 \textcolor{red}{创建一个Person父类} 创建一个Person父类

public class Person {
    
    public void run()//重写了run
    {
        System.out.println("Person run");

    }

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

}

创建一个 S t u d e n t 子类 \textcolor{red}{创建一个Student子类} 创建一个Student子类

public class Student extends Person{

    @Override //alt+fn+insert进行重写
    public void run() {//重写了run
        System.out.println("son");
    }
    
    public viod aaa()//子类中有aaa方法,而父类中无aaa方法。父类可以指向子类,但是不能调用子类的方法。
    {
        System.out.println("Person aaa");
    }
}

创建一个 m a i n 类运行 \textcolor{red}{创建一个main类运行} 创建一个main类运行

public class Application {
    public static void main(String[] args) {
        一个对象的实际类型是确定的,都是Student()
        //但是,可以指向的引用类型不确定,比如Person、Object。父类的引用指向子类
        //对象能执行的方法,主要看看对象左边的类型。
        Student s1 = new Student();//子类能调用的方法都是自己的,或者继承父类的
        //下面那个是多态写法,父类的引用指向子类。并且有重写的方法
        Person s2 = new Student();//父类可以指向子类,但是不能调用子类的方法。这最终还是指向父类自己。
        Object s3 =new Student();//祖父辈的引用也指向子类

        s2.eat();//输出:eat。s2本来指向的就是父类
        s1.eat();//s1中没有eat方法,但是s1可以继承父类,可以调用父类的方法


        s2.run();//子类重写了父类的方法,执行了子类。  输出:son
        s1.run();// 输出:son
        
        //s2.aaa();//这是错误的,父类可以指向子类,但是不能调用子类的方法。
    }
}

4.3.2 instanceof 判断类型 和 类型之间的转换

判断类型。用instanceof判断类型之间是否有关系,有关系true,没关系false。  a对象 instanceof B类型  。a与B是否是包含关系
    a可以是B类型的父亲,祖父,儿子,孙子也可以是自己关系。

例子:

创建一个 P e r s o n 父类 \textcolor{red}{创建一个Person父类} 创建一个Person父类

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

}

创建一个 S t u d e n t 子类 \textcolor{red}{创建一个Student子类} 创建一个Student子类

public class Student extends Person{
    public void go()
    {
        System.out.println("Student go");
    }
}

创建一个 m a i n 类运行 \textcolor{red}{创建一个main类运行} 创建一个main类运行(用instanceof来判断类型是否是包含关系)

//判断类型。用instanceof判断类型之间是否有关系,有关系true,没关系false
对象+instanceof +另一个类型.//有关系true,没关系false
public class Application {
    public static void main(String[] args) {

        //Object>Person>Student
        //Object>Person>Teacher
        Object obj = new Student();//多态里讲过,爸爸的爸爸也可以指向子类
        System.out.println(obj instanceof Student);//true
        System.out.println(obj instanceof Teacher);//false
        System.out.println(obj instanceof Person);//true
        System.out.println(obj instanceof Object);//true
        System.out.println(obj instanceof String);//false。String是object的子类,但与Student子类无包含关系

        System.out.println("====================================");
        Person p = new Student();
        System.out.println(p instanceof Student); //true
        System.out.println(p instanceof Person);  //true
        System.out.println(p instanceof Object);  //true

        System.out.println("====================================");
        Student s = new Student();
        System.out.println(s instanceof Student);//true。Student与自己是有关系
        System.out.println(s instanceof Person);//true。Student与Person是有父子关系
        System.out.println(s instanceof Object);//true。Student与Object也是有父子关系,是祖父与孙子之间的关系。
    }
}
  • 类型转换:

以前学过基本类型的转换,高---->低 需要强制转换。 低----->高,不需要强制转换
//引用类型之间的转换: 父 子 。父—>子 强制转换 ,向下转型 。(引用类型:数组、类、接口)
//子–>父 向上转型,自动转换,向上转型
//方便方法的调用,减少重复的代码

创建一个 m a i n 类运行 \textcolor{red}{创建一个main类运行} 创建一个main类运行(引用类型的转换)

//以前学过基本类型的转换,高---->低 需要强制转换。 低----->高,不需要强制转换
//类型之间的转换: 父 子 。父--->子 强制转换 ,向下转型
//              子--->父 向上转型,自动转换,向上转型
//             方便方法的调用,减少重复的代码
public class Application {
    public static void main(String[] args) {
        //类型之间的转换: 父 子 。父--->子强制转换 ,向下转型
        //Person父类高的一方        Student子类低的一方
        Person s = new Student();
        //s.go()是不行的,因为Person中没有go()方法,而在Student中有go方法。
        //Person是高类型,Student是低类型,高转低。需要强制转换,使用Student将这个对象转换为Student类型,我们就可以使用Student类型的方法
        Student s1 = (Student) s;//将原来Person类的s,强制转换成Student类型的s1
        s1.go();
        ((Student)s).go();//或者把上面两步合在一起  Student s1 = (Student) s;s1.go();


        //子--->父 向上转型,自动转换。子类到父类会丢失自己的方法
        Student a =new Student();
        a.go();
        Person p = a;//a是Student类型,是子类。p是Person类型是父类。由子类到父类自动转换
        p.run();


    }
}

5. static关键字详解

5.1 static的属性和方法的用法

public class Student {
    private static int age;//静态变量
    private double score;//非静态变量

    public void run()//非静态的方法
    {
        System.out.println("非 static run");
        //非静态方法可以访问静态方法
        //go();
    }

    public static void go()//static在使用时是跟类一起加载,在加载时没有非静态方法,所以后面非静态方法需要实例化
    {
        System.out.println("static go");
    }
    
    public static void main(String[] args) {
        Student s = new Student();
        System.out.println(s.age);//通过对象调用属性
        System.out.println(s.score);//通过对象调用属性
        System.out.println(Student.age);//通过Student类来调用静态变量age,无法调用非静态变量。
        //静态属性多采用类名来调用
        
        Student s1 = new Student();
        s1.run();//通过对象调用非静态方法
        s1.go();//通过对象调用静态方法

        new Student().run();//或者通过类直接调用非静态方法
        Student.go();//通过类直接调用静态方法。在同一类中也可以直接用go()
    }
}

5.2 static静态代码块

public class Person {//代码块(匿名代码块),创建对象的时候就自己创建了。首先执行
//用于赋初始值
    {
        System.out.println("匿名代码块");
    }

    static{//静态代码块,第二个执行
        //加载一写初始化设置。类加载的时候直接执行,永久执行一次
        System.out.println("静态代码块");
    }

    public Person(){//构造方法最后执行
        System.out.println("构造方法");
    }


    public static void main(String[] args) {
        Person p1 = new Person();//执行结果:匿名代码块 静态代码块  构造方法
        System.out.println("============");
        Person p2 = new Person();//执行结果: 匿名代码块 构造方法 (stitic代码块只执行一次,所以没有了静态代码块)

    }
}

5.3 静态导入包(基本不用,了解就可以)

//很少人这样用
//静态导入包,在main中可以直接用randon,可以不用Math.random
import static java.lang.Math.random;
import static java.lang.Math.PI;
public class Test {
    public static void main(String[] args) {
        System.out.println(Math.random());//输出一个随机数
        System.out.println(random());//静态导入包输出一个随机数
        System.out.println(PI);//静态导入包输出一个随机数
    }
}
//另外final 常量。只有方法才能被重写。  final也可以修饰类 public final class Person 修饰类不可以被继承

6. 抽象类(了解即可)

在这里插入图片描述

抽象类的含义:abstract在类、方法前修饰,起到约束作用。让别人来完成重写方法。
抽象类的特点:

1.不能new这个抽象类,只能靠子类去实现它,可以通过new子类来实例化,起到约束的作用。
2.抽象类中可以有普通的方法
3.有抽象方法的类一定是抽象类
抽象类的实质是:抽象的抽象,起到约束作用。

创建一个 A c t i o n 类运行 \textcolor{red}{创建一个Action类运行} 创建一个Action类运行

//抽象类:类。需要去继承。   类可以单继承,但是接口可以实现多继承。
public abstract class Action {//变成抽象类

    //约束,让其他人帮忙实现
    //abstract抽象方法,只有方法的名字,没有方法的实现。
    public abstract  void do_something();

}

创建一个 A 类运行 , 用 A 类来继承 A c t i o n 类 \textcolor{red}{创建一个A类运行,用A类来继承Action类} 创建一个A类运行,A类来继承Action

//实现Action的dosomething方法
//抽象类的所有方法,继承它的子类,都必须去重写它的方法,除非这个子类也是抽象类
public class A extends Action {
    @Override//重写Action类中没有写的方法
    public void do_something() {

    }
}

7.接口(超级重要)

在这里插入图片描述

接口的作用:
    1.接口特等的约束
    2.定义一些方法,让不同人实现
    3.接口的方法都是public abstract
    4.常量都是lublic static final
    5.接口不能被直接new,接口中没有构造方法。接口想要使用必须靠类来重写接口中的方法
    6.implements可以实现多个接口,也就是多个继承

创建一个 U s e r S e r v i c e 接口 \textcolor{red}{创建一个UserService接口} 创建一个UserService接口

//接口为interface来定义
//接口只是来定义的。接口都需要实现类
public interface UserService {
    //接口中定义的属性都是常量public static final ,可以不写
    int age=99;//一般不再接口中定义常量

    //接口中的所有定义方法都是抽象的,都是public abstract。并且public abstract可以在接口中不用写
    void add(String name);
    void deleat(String name);
    void update(String name);
    void query(String name);
}

创建一个 T i m e S e r v i c e 接口 \textcolor{red}{创建一个TimeService接口} 创建一个TimeService接口

public interface TimeService {
    void timerr();
}

创建一个 U s e r S e r v i c e I m p l 类来实现接口 \textcolor{red}{创建一个UserServiceImpl类来实现接口} 创建一个UserServiceImpl类来实现接口

//接口的实现类,是public class+接口名Impl+implements+接口名
//想要实现接口的类,必须重写接口的方法。实现类可以实现多个接口,有多继承
//抽象类是通过 extends
快捷键ctrl+i可以快速添加方法
public class UserServiceImpl implements UserService,TimeService {//接口可以实现多继承
    @Override
    public void add(String name) {//UserService接口

    }
    @Override
    public void deleat(String name) {//UserService接口

    }

    @Override
    public void update(String name) {//UserService接口

    }

    @Override
    public void query(String name) {//UserService接口

    }

    @Override
    public void timerr() {//TimerService的接口

    }
}

8 内部类(了解即可)

在这里插入图片描述

8.1成员内部类

创建一个 O u t e r 外部类类,这个 O u t e r 中有一个内部类 I n n e r \textcolor{red}{创建一个Outer外部类类,这个Outer中有一个内部类Inner} 创建一个Outer外部类类,这个Outer中有一个内部类Inner

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

创建运行 m a i n ,通过外部类来访问内部类 \textcolor{red}{创建运行main,通过外部类来访问内部类} 创建运行main,通过外部类来访问内部类

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

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

8.2静态内部类

创建一个 O u t e r 外部类类,这个 O u t e r 中有一个内部类 I n n e r \textcolor{red}{创建一个Outer外部类类,这个Outer中有一个内部类Inner} 创建一个Outer外部类类,这个Outer中有一个内部类Inner

public class Outer {//外部类

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

    //==========================================================

    public static class Inner{//内部类,在一个类中定义一个类。静态内部类无妨访问非静态的外部类
        public void in()//内部类的方法
        {
            System.out.println("这是内部类的方法");
        }

        public void GETId()//
        {     //下面两个会报错,因为静态类会先加载,无法访问非静态类
//            System.out.println(id);
//            out();
        }
    }
}

8.3 局部内部类

public class Outer {
    //方法中定义的类,叫做局部内部类
    public void method(){
        class Inner{

        }
    }
}

8.4匿名内部类

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

    }
}

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值