Java基础---面向对象编程基础部分

1.什么是面向过程的编程?

开发一个又一个的方法,有数据要处理,我们就调方法来处理。

2.什么是面向对象的编程?

开发一个一个的对象来处理数据,把数据交给对象,再调用对象的方法来完成对数据的处理。

3.什么是对象?

对象本质上是一种特殊的数据结构。

4.对象是怎么来的?

应用class来创建对象,class就是类,也称为对象的设计图(或者对象的模板)

5.类和对象的一些注意事项

  • 类名建议用英文单词,首字母大写,满足驼峰模式,且要有意义,比如:Student、Car…
  • 类中定义的变量也称为成员变量(对象的属性),类中定义的方法也称为成员方法(对象的行为)
  • 成员变量本身存在默认值,同学们在定义成员变量时一般来说不需要赋初始值(没有意义)。
  • 一个代码文件中,可以写多个class类,但有且只能有一个类用public修饰,且public修饰的类名必须成为代码文件名。
  • 对象与对象之间的数据不会相互影响,但多个变量指向同一个对象时就会相互影响了。
  • 如果某个对象没有一个变量引用它,则该对象无法被操作了,该对象会成为所谓的垃圾对象。Java存在自动垃圾回收机制,会自动清除掉垃圾对象,程序员不用操心。

6.this关键字

  • this就是一个变量,可以用在方法中,来拿到当前对象。
  • this主要用来解决:变量名称冲突问题的。

7.构造方法

构造方法的语法格式

//             类名
public class Student {       

        /** 构造器 */  
    // 权限修饰符    类名
        public     Student() {                 
            ...        
    }
}

注意:构造方法是一个特殊的方法 名字必须与所在类的名字一样而且它不能写返回值类型 

构造方法的特点

  • 创建对象时,对象会去调用构造器
Student s = new Student();
//创建对象时,会根据new Student()括号中有没有参数类型调用不同的构造器

构造方法的常见应用场景

创建对象时,同时完成对对象成员变量(属性)的初始化赋值。

构造方法的注意事项 

  • 类在设计时,如果不写构造器,Java是会为类自动生成一个无参构造器的。
  • 一旦定义了有参数构造器,Java就不会帮我们的类自动生成无参构造器了,此时就建议自己手写一个无参数构造器出来了。

构造方法的作用

  • 创建对象
  • 初始化成员变量(给对象的成员变量(对象的属性赋值))

构造方法的分类

  • 无参构造方法
  • 有参构造方法

8.一个类中都可以有什么?

1.成员变量        2.成员方法       3.静态变量        4.静态方法        5.构造方法(构造器)       

6.构造代码块    7.静态代码块    8.非静态常量     9.静态常量

9.实体类

什么是实体类?

就是一种特殊形式的类。通常将代表现实生活中的具体事物的类称为实体类(JavaBean 或 entity 或 pojo )

一个标准的JavaBean是什么样的呢?

  • 类名符合类的命名规则,做到见文知意
  • 提供至少两个构造方法:
    • 无参构造
    • 全参构造
  • 注意:
    • 当类中如果没有任何一个构造方法的时候,系统会默认提供一个无参构造                   
    • 如果类中已经明确的写出任何一个构造方法,则系统不会再提供默认的无参构造
    • 如果还要使用无参构造,则必须明确的写出无参构造
  • 成员变量(属性)使用private(私有)修饰
  • 实体类要对外提供相应的公用的get和set方法:getXxx ,setXxx
  • 如果该类还有其他的行为(能力),也必须将其写出来

实体类有啥应用场景?

实体类只负责数据存取,而对数据的处理交给其他类来完成,以实现数据和数据业务处理相分离。

//例如:
public class Student {
    //成员变量
    private String name;   
    private double score;
    
    //无参构造方法      
    //有参构造方法
    // getter setter方法
}

10.成员变量和局部变量的区别

区别 成员变量 局部变量
类中位置不同 类中,方法外 常见于方法中
初始化值不同 有默认值, 不需要初始化赋值 没有默认值,使用之前必须完成赋值
内存位置不同 堆内存 栈内存
作用域不同  整个对象 在所归属的方法大括号中
生命周期不同 与对象共存亡 随着方法的调用而生,随着方法的运行结束而亡

11.面向对象的三大特征:封装、继承、多态

11.1封装

封装的定义:封装就是用类设计对象处理某一个事物的数据时,应该把要处理的数据,以及处理这些数据的方法,设计到一个对象中去。

封装的设计规范:合理隐藏,合理暴露

11.1.1static关键字

11.1.1.1 static修饰成员变量
定义
  • static叫静态,可以修饰成员变量、成员方法。静态存储的区域叫静态区,静态区在堆空间中。
  • 用static修饰成员变量、成员方法,如果要用权限修饰符一般用public(公用的)
成员变量按照有无static修饰,分为两种
  • 类变量也叫静态成员变量(属于类的变量):有static修饰,属于类,在计算机里只有一份,会被类的全部对象共享。
  • 实例变量也叫成员变量(属于对象的变量):无static修饰,属于每个对象的。
调用方法

用static修饰的变量调用方法:

  • 类名.静态成员变量 (推荐)
  • 对象.静态成员变量(不推荐)

无static修饰的变量调用方法:对象名.实例变量

类变量(静态变量)的应用场景

在开发中,如果某个数据只需要一份,且希望能够被共享(访问、修改),则该数据可以定义成类变量来记住。

例如:系统启动后,要求用户类可以记住自己创建了多少个用户对象了。

11.1.1.2 static修饰成员方法
定义

类方法(静态方法):有static修饰的成员方法,属于类。

成员方法按照有无static修饰,分为两种
  • 类方法(静态方法):有static修饰的成员方法,属于类
  • 实例方法(非静态方法):无static修饰的成员方法,属于对象。

创建类方法(静态方法)的语法格式

修饰符 static 返回值类型 方法名(){
        ...
}

创建实例方法(非静态方法)的语法格式 

public void printPass(){
      ...
}
 调用方法:

用static修饰的成员方法调用方法:

  • 类名.类方法名(静态方法名) (推荐)

  • 对象名.类方法名(静态方法名)(不推荐)

无static修饰的成员方法调用方法: 对象.实例方法(成员方法名)

 静态方法(static修饰方法)缺点
  • 同一个类中,静态方法只能访问静态修饰的成员(静态只能访问静态)
  • 静态方法(类方法)中不能直接使用非静态属性(成员变量)或者方法(成员方法)
  • 静态方法中不能直接调用非静态的成员,如果要进行调用,则需要使用类名进行调用
  • this这个内置对象只存在于非静态中,静态中不存在this这个内置对象 
类方法(静态方法)的常见应用场景
  • 类方法(静态方法)最常见的应用场景是编写工具类
  • 当一个类的所有对象都具有某个功能的时候,并且随处都需要使用是就可以将功能写出静态。
  • 工具类是什么?
    • 工具类中的方法都是一些类方法(静态方法),每个方法都是用来完成一个功能的,工具类是为了方便别人调用的。
使用类方法和实例方法时的注意事项
  • 类方法(静态方法)中可以直接访问类的成员(静态成员变量),不可以直接访问实例成员(成员变量)。
  • 实例方法(成员方法)中既可以直接访问类成员(静态成员变量),也可以直接访问实例成员(成员变量)。 实例方法中可以出现this关键字,类方法中不可以出现this关键字的。
11.1.1.3 代码块

代码块概述:代码块是类的5大成分之一(成员变量、构造方法、方法、代码块、内部类)。

代码块按照有无static修饰分为两种:静态代码块和构造代码块

静态代码块(static修饰)

语法格式:

static {... }

特点:类加载时自动执行,由于类只会加载一次,所以静态代码块也只会执行一次。不论创建多少个对象,都只执行一次。 

作用:完成类的初始化,例如:对类变量的初始化赋值。

应用场景:

  • 静态代码块是进行类中的数据初始化,且这些数据只初始化一次的时候。      
  • 当该类的所有对象共享同一个数据的时候,通常该数据只需要初始化一次,会使用静态代码块进行初始化。

注意:静态代码块中只能使用其它static修饰的变量

构造代码块(无static修饰)

语法格式:

{...}

构造代码块(成员代码块/普通代码块):直接写在类中的代码块,每次调用构造方法都会执行一次构造代码块。 

特点:每次创建对象时,执行构造代码块,并在构造器前执行。

作用:和构造器一样,都是用来完成对象的初始化的,例如:对实例变量进行初始化赋值。

三种代码块的执行顺序: 静态代码块 > 构造代码块(成员代码块/普通代码块) > 构造方法(构造器) 

11.2 继承

继承定义:Java中提供了一个关键字extends,用这个关键字,可以让一个类和另一个类建立起父子关系。

继承的特点:

  • 子类能继承父类的非私有成员(成员变量、成员方法)。
  • 继承后对象的创建,子类的对象是由子类、父类共同完成的。

继承的语法格式

public class 子类名 extends 父类名{
        ...
}

什么样的内容不能被子类继承?

  • 子类不能继承父类中用权限修饰符private修饰的成员和方法。
  • 构造方法属于每个类独有的功能,不能被继承。子类虽然不能继承父类的构造方法,但可以调用父类的构造方法。子类通过super关键字调用父类的构造方法。
  • 因为子类不能继承父类的构造方法,如果有子类要使用构造方法,那么应该怎么办呢?
    • 解决方法:在子类中自己写,这样就可以使用new关键字创建子类对象

在子类中写构造方法会出现两种情况:

  • 情况1:父类中的所以属性(成员变量)都是公用的(public),父类中的所以属性是能被子类继承的,这时在子类中写子类的构造方法可以用this关键字,也可以使用super关键字调用父类的构造方法。
父类Person的所以属性(成员):
 public String name;
 public int age;

子类Student:继承了父类


在子类中写的无参构造:
public Student() {

}


在子类中写的有参构造:
 public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
  • 情况2:父类中有私有属性(成员变量),父类中私有属性是不能被子类继承的,这时在子类中写子类的构造方法只能使用super关键字调用父类的构造方法。
父类Person的所以属性(成员):
 private String name;
 public int age;

子类Student:继承了父类


在子类中写的无参构造:
public Student() {

}


在子类中写的有参构造:
 public Student(String name, int age) {
        super(name, age);
}

 super和this的区别:

  • 通过super可以直接操作父类,通过this操作子类。    
  • super:表示父类对象的引用,但是仅仅只是表示引用,super并不是一个真实存在的对象,只是一种表示形式。    通过super关键字调用父类的属性或者方法。
  • super和this的区别   
    • this是一个真实存在的对象(当前对象)    
    • super仅仅只是父类的一个表示符,不是一个真实存在的父类对象    
  • super和this除了可以操作成员变量和成员方法之外还可以操作构造方法    
    • super();调用父类的无参构造    
    • super(实参);调用父类的有参  
    •  this();调用当前类的无参    
    • this(实参);调用当前类的有参
  • 不管是this,还是super如果要调用构造方法,则必须在构造方法内才能进行调用。
  • this和super在构造方法中调用别的或者父类的构造方法时要求出现在第一行
  • 调用成员方法  
    •  this.方法()    
    • super.方法()

继承优缺点

  • 优点:继承可以提高代码的复用性,便于维护。继承可以使类和类之间产生关系。
  • 缺点:由于继承造成了类和类之间存在的关系,那么也就增强了类和类之间的耦合度, 当父类发生改变的时候可能子类也可能需要改变,削弱了子类的独立性。

继承相关的注意事项

 Java是单继承的,Java中的类不支持多继承,但是支持多层继承。

11.2.1 方法重写

当子类觉得父类中的某个方法不好用,或者无法满足自己的需求时,子类可以重写一个与父类方法名称相同、参数列表相同、返回值相同的方法,去覆盖父类的这个方法,这就是方法重写。

注意:

  • 重写后,方法的访问,Java会遵循就近原则 。
  • 方法重写必须存在继承关系,方法能不能被继承下来只和访问权限修饰符有关。
  • 重写小技巧:使用Override注解,他可以指定java编译器,检查我们方法重写的格式是否正确,代码可读性也会更好。
  • 子类重写父类方法时,访问权限必须大于或者等于父类该方法的权限( public > protected > 缺省 )。
  • 重写的方法返回值类型,必须与被重写方法的返回值类型一样,或者范围更小。
  • 私有方法、静态方法和final修饰的方法不能被重写,如果重写会报错的。

11.2.2 子类构造器的特点

  • 子类的全部构造器,都会先调用父类的构造器,再执行自己。
  • 在Java中,如果存在继承关系,在创建子类的对象时,先会调用父类的构造方法,然后才会调用子类的构造方法的原因是:因为,Java需要确保子类在创建对象的时候,类中的所有属性都能进行初始化。因为子类中有可能会使用到一些需要继承下来的内容(有可能会被私有化),通过先执行父类,让父类先初始化,保证子类能够正常初始化。
  • 子类构造器是如何实现调用父类构造器的
    • 默认情况下,子类全部构造器的第一行代码都是 super()(写不写都有),它会调用父类的无参数构造器。
    • 如果父类没有无参数构造器,则我们必须在子类构造器的第一行手写super(….),指定去调用父类的有参数构造器

11.2. 3 Object类

  • object类是java所有类的祖宗类。我们写的任何一个类,其实都是object的子类或子孙类(派生类)。
  • JAVA中我们将Object类称为根类/基类/超级父类
  • Java中任意的一个类都可以使用继承自Object中的属性和方法

11.3 多态

多态是在继承/实现情况下的一种现象,表现为:对象多态、行为多态。

多态的前提:有继承/实现关系;存在父类引用子类对象;存在方法重写

多态的一个注意事项:多态是对象、行为的多态,Java中的属性(成员变量)不谈多态。

使用多态的好处:

  • 在多态形式下,右边对象是解耦合的,更便于扩展和维护。
  • 定义方法时,使用父类类型的形参,可以接收一切子类对象,扩展性更强、更便利。

多态下会产生的一个问题,怎么解决?

  • 多态下不能使用子类的独有功能。
  • 只能使用继承下来的属性和方法。
  • 如果子类中重写了父类的方法,调用方法时会执行子类中重写的方法,如果子类没有重写父类的方法则会调用父类的方法。
  • 我们需要使用子类特有的属性或者方法的时候,就需要将父类的类型重新转换回子类的类(类型转换)

11.3.1 类型转换

自动类型转换:父类类型 变量名 = new 子类();

强制类型转换:子类类型 变量名 = (子类类型) 父类变量;

强制类型转换的一个注意事项:

  • 存在继承/实现关系就可以在编译阶段进行强制类型转换,编译阶段不会报错。
  • 运行时,如果发现对象的真实类型与强转后的类型不同,就会报类型转换异常(ClassCastException)的错误出来。

强转前,Java建议:使用instanceof关键字,判断父类的引用是当前子类类型的对象(判断当前对象的真实类型),再进行强转。

11.3.2 final关键字

  • final 关键字是最终的意思,可以修饰(类、方法、变量)。
  • 修饰类:该类被称为最终类,特点是它修饰的类不能被继承。
  • 修饰方法:该方法被称为最终方法,特点是它修饰的方法够被继承,但是不能被重写。
  • 修饰变量:该变量只能被赋值一次。final修饰的变量叫做常量(值不可改变)。

final修饰变量的注意

  • final修饰基本类型的变量,变量存储的数据(值)不能被改变。
  • final修饰引用类型的变量,变量存储的地址不能被改变(表示引用不可变),但地址所指向对象中的内容是可以被改变的。

11.3.3 常量

  •  使用了 static final 修饰的成员变量就被称为常量
  •  作用:通常用于记录系统的配置信息。
public class School{    

    public static final String NAME  = “大学教育";

} 

注意!常量名的命名规范:建议使用大写英文单词,多个单词使用下划线连接起来。

使用常量记录系统配置信息的优势、执行原理:

  • 代码可读性更好,可维护性也更好。
  • 程序编译后,常量会被“宏替换”:出现常量的地方全部会被替换成其记住的字面量,这样可以保证使用常量和直接用字面量的性能是一样的。

11.3.4 抽象类​​​​​​​

什么是抽象类?
  • 在Java中有一个关键字叫:abstract,它就是抽象的意思,可以用它修饰类、成员方法。
  • abstract修饰的方法叫做抽象方法,没有方法体,主要作用是用来定义规则,让子类去重写
  • abstract修饰的类叫做抽象类,抽象类比普通类功能更强的地方在于抽象类中可以定义抽象规则。
抽象类的语法格式
//抽象类
修饰符 abstract class 类名{ 
	//抽象方法
    修饰符 abstract 返回值类型 方法名称(形参列表);
 }
抽象类最主要的特点

抽象类不能创建对象,仅作为一种特殊的父类,让子类继承并实现。

抽象类的注意事项
  • 抽象类中不一定有抽象方法,有抽象方法的类一定是抽象类。
  • 类该有的成员(成员变量、方法、构造方法)抽象类都可以有。
  • 一个类继承抽象类,必须重写完抽象类的全部抽象方法,否则这个类也必须定义成抽象类
  • 如果子类也是抽象类,则可以不用重写父类的抽象方法。

抽象类的作用:主要是用来给子类继承。

请问final关键字能不能和abstract关键字连用?    
  • 不能连用:final最终,修饰的类不能被继承,修饰的方法能继承,但不能被重写,而abstract修饰的方法就是为了给子类重写,修饰的类就是为了被继承。

抽象类既然不能直接通过构造方法创建其对象,那么抽象类中的构造方法的作用是什么?  

  • 用来帮助我们进行成员变量的初始化作用。
抽象类的好处
  • 多个类中只要有重复代码(包括相同的方法签名),我们都应该抽取到父类中去,减少代码的冗余。此时,父类中就有可能存在只有方法签名的方法,这时,父类必定是一个抽象类了,我们抽出这样的抽象类,就是为了更好的支持多态。
抽象类的写法(抽象类相当于一个模板)
  • 定义一个抽象类。
  • 在里面定义2个方法
    • 一个是模板方法:把相同代码放里面去。

    • 一个是抽象方法:具体实现交给子类完成。

  • 定义子类继承抽象类,重写抽象方法。

  • 创建子类对象,调用模板方法完成功能。

11.3.5 接口

接口的定义
  • Java提供了一个关键字interface,用这个关键字我们可以定义出一个特殊的结构:接口。
  • 接口:接口可以理解为一个极致的抽象类(不属于类,是一个独立的数据类型)
  • 接口中所有的方法都是抽象方法(JDK1.8之前)
接口的语法格式
public interface 接口名 {
       //常量
       //抽象方法
} 
类实现接口的语法格式 
//一个类实现一个接口的语法格式:
修饰符 class 实现类名 implements 接口{
    //重写完接口中所有抽象方法
}


//一个类实现多个接口的语法格式:
修饰符 class 实现类名 implements 接口1, 接口2, 接口3 , ... {
    //重写完所有实现接口中所有抽象方法
}
接口存在的重要意义 
  • 定义统一规范,约束一类事物的功能设计
  • 为后续软件设计,提高程序的扩展性(后续了解)
注意接口与继承的区别
  • 类与类之间的继承关系:只支持单继承,继承用extends修饰      
  • 类与接口之间的实现关系:支持多实现,实现用implements修饰
接口注意事项
  • 接口中的方法全部是公有的抽象方法: public abstract修饰(系统默认)
  • 接口中的变量全部是公有的静态常量: public static final修饰(系统默认)
  • 接口中的抽象方法和静态常量没有写修饰符,系统会自动提供。
  • 接口由于全部是抽象方法,所以接口只是用来定义规则,如果要是用这些规则,则需要使用类来实现。注意:抽象方法是没有方法体的。
  • ★★★注意:接口中不存在构造方法的 。因为接口存在的意义就是用来给类进行实现(定义规则用来限制类)
  • 一个类实现接口,必须重写完全部接口的全部抽象方法,如果不重写完所有的抽象方法,那么这个类需要定义成抽象类。    
  • 如果一个类(非抽象类)实现类某个接口,则该类需要重写接口中所有的抽象方法
  • 注意:接口不能创建对象;接口是用来被类实现(implements)的,实现接口的类称为实现类。    
  • 接口和抽象类一样,不能直接创建自己的对象。如果要创建对象,则必须创建接口实现类的对象。
  • 一个类可以实现多个接口(接口可以理解成干爹),实现类实现多个接口,必须重写完全部接口的全部抽象方法,否则实现类需要定义成抽象类。
  • 接口可以继承接口,并且可以多继承,也就是一个接口可以直接多个接口。再发开中,如果要做功能相近的接口的功能整合,则会使用到接口的多继承。否则,开发中,尽可能的让接口独立 ,少用一个接口继承多个接口  
  • 类实现多个接口的情况(多用)远远多于一个接口继承多个接口(少用),因为类的多实现可以降低耦合性(类与接口或者接口与接口之间产生的直接链接)
接口的新特性

JDK 8开始,接口中的方法除了抽象方法,还可以有带有方法体的方法。

1.可以有使用default关键字修饰的方法 默认方法:使用用default修饰,默认会被加上public修饰。 ★注意:只能使用接口的实现类对象调用

2.可以有静态方法(使用) 类方法(静态方法):使用static修饰,默认会被加上public修饰。 ★注意:只能用接口名来调用。

3.可以有私有修饰的方法(使用private修饰)(jdk9开始的)

12.内部类

12.1 定义

内部类是类中的五大成分之一(成员变量、方法、构造方法、内部类、代码块),如果一个类定义在另一个类的内部,这个类就是内部类。

12.2 使用场景

当一个类的内部,包含了一个完整的事物,且这个事物没有必要单独设计时,就可以把这个事物设计成内部类。

12.3 内部类有四种形式

12.3.1 成员内部类

定义

成员内部类就是类中的一个普通成员,类似前面我们学过的普通的成员变量、成员方法。

例如:

public class A {
   // 成员内部类   
    public class B {   
    
    }
}

注意:JDK16之前,成员内部类中不能定义静态成员,JDK 16开始可以定义静态成员了 

创建对象的语法格式
外部类名.内部类名 对象名 = new 外部类(...).new 内部类(...);
成员内部类中访问其他成员的特点 
  • 和前面学过的实例方法一样,成员内部类的实例方法中,同样可以直接访问外部类的实例成员、静态成员。
  • 可以在成员内部类的实例方法中,拿到当前外部类对象,格式是:外部类名.this 。

12.3.2 静态内部类

定义

有static修饰的内部类,属于外部类自己持有。

例如:

public class A{
    // 静态内部类
    public static class B{

   }
}
创建对象的语法格式
外部类名.内部类名 对象名 = new 外部类.内部类(…);
静态内部类中访问外部类成员的特点 

可以(只能)直接访问外部类的静态成员,不可以直接访问外部类的实例成员

12.3.3 局部内部类

定义

局部内部类是定义在在方法中、代码块中、构造器等执行体中。

例如:

public class Test {
   public static void main(String[] args) {
    //主函数
 }
    public static void add(){
         class A{
         }  

        abstract class B{ 
         }

        interface C{ 
        }
     }
}

12.3.4 匿名内部类[重点]

定义
  • 匿名内部类就是一种特殊的局部内部类。
  • 所谓匿名:指的是程序员不需要为这个类声明名字。
特点
  • 匿名内部类本质就是一个子类,并会立即创建出一个子类对象。
作用
  • 用于更方便的创建一个子类对象。
创建语法格式
new  类或接口(参数值…) {
       类体(一般是方法重写);
};
使用场景
  • 通常作为一个参数传输给方法。

13.枚举

定义

枚举是一种特殊类。

语法格式

修饰符 enum 枚举类名{
       名称1 ,  名称2, ... ; 
       其他成员…
}

注意

  • 枚举类中的第一行,只能写一些合法的标识符(名称),多个名称用逗号隔开。
  • 枚举类第一行只能罗列出一些常量名称,不能进行第二次赋值
  • 这些名称,本质是常量,每个常量都会记住枚举类的一个对象,枚举类的对象可以进行访问。

枚举类的特点

  • 枚举类的第一行只能罗列一些名称,这些名称都是常量,并且每个常量记住的都是枚举类的一个对象。
  • 枚举类的构造器都是私有的(写不写都只能是私有的),因此,枚举类对外不能创建对象。
  • 枚举都是最终类,不可以被继承。
  • 枚举类中,从第二行开始,可以定义类的其他各种成员。
  • 编译器为枚举类新增了几个方法,并且枚举类都是继承:java.lang.Enum类的,从enum类也会继承到一些方法。

14.泛型

定义

定义类、接口、方法时,同时声明了一个或者多个类型变量(如:) ,称为泛型类、泛型接口,泛型方法、它们统称为泛型。

public class ArrayList{
    . . .
}

作用:泛型提供了在编译阶段约束所能操作的数据类型,并自动进行检查的能力!这样可以避免强制类型转换,及其可能出现的异常。

泛型的本质:把具体的数据类型作为参数传给类型变量。

泛型类语法格式

修饰符 class 类名<类型变量,类型变量,...> { 

}

注意:类型变量建议用大写的英文字母,常用的有:E、T、K、V 等

泛型接口语法格式

修饰符 interface 接口名<类型变量,类型变量,...> { 

}

泛型方法语法格式

修饰符 <类型变量,类型变量, ...>  返回值类型 方法名(形参列表) { 

 }

通配符

就是 “?” ,可以在“使用泛型”的时候代表一切类型;  E T K V 是在定义泛型的时候使用。

泛型的上下限

  • 泛型上限:   ? extends A:   ? 能接收的必须是Car或者其子类 。  
  • 泛型下限:  ?  super A : ?  能接收的必须是Car或者其父类。

泛型的擦除问题和注意事项

  • 泛型是工作在编译阶段的,一旦程序编译成class文件,class文件中就不存在泛型了,这就是泛型擦除。
  • 泛型不支持基本数据类型,只能支持对象类型(引用数据类型)。

你可能感兴趣的:(Java,java,开发语言,idea)