泛型 1、什么是泛型 Java泛型是Java 5引入的一个新特性,它允许在编译时定义类型参数,使代码更加灵活和可重用。...这个类有一个私有的成员变量t,其类型为T。我们可以通过调用set()和get()方法来设置和获取t的值。...类名后的 代表占位符,表示当前类是一个泛型类 了解: 【规范】类型形参一般使用一个大写字母表示,常用的名称有: E 表示 Element K 表示 Key V 表示 Value N 表示...// 编译错误,因为 String 不是 Number 的子类型 了解: 没有指定类型边界 E,可以视为 E extends Object 到此,我们的 Java 泛型博客之旅就告一段落了。...希望我的分享对你有所帮助。如果你有任何问题或想法,欢迎在评论中留言。让我们继续探索 Java 世界,共同成长!✌️
表示通配符,它的语义是表示未知的类型。通配符可以用作方法的形参、字段的定义、局部变量的定义,以及有的时候作为函数的返回值。通配符不能作为实参调用泛型方法,不能创建对象,或者派生子类型。...比如编译器编译的时候 list.set(0, xxx),这里的入参的类型就会是 CAP#1, list.get(0) 返回的类型就是 CAP#2,因为没有一个泛型参数来告诉编译器说 CAP#1 和 CAP...下图是编译器实际的提示信息:从上面的图也可以看出,第二次调用方法时,类型又变成 CAP#3 和 CAP#4 了,这也证明了每次编译器都会认为是一个新的类型。...方法的形参类型是 Object 类型,和 Node 类中泛型擦除后的类型相同,说明这个方法才是真正重载了 Node 类中的方法。...同时在 MyNode 类中不允许自己定义形参为 Object 类型的 setData() 方法了,如果定义了则无法编译:经过编译器编译后的代码等效为如下的代码:public class Node {
一提到参数,最熟悉的就是定义方法时有形参列表,普通方法的形参列表中,每个形参的数据类型是确定的,而变量是一个参数。...在调用普通方法时需要传入对应形参数据类型的变量(实参),若传入的实参与形参定义的数据类型不匹配,则会报错 那参数化类型是什么意思呢?...以方法的定义为例,在方法定义时,将方法签名中的形参的数据类型也设置为参数(也可称之为类型参数),在调用该方法时再从外部传入一个具体的数据类型和变量 泛型的本质是为了将类型参数化, 也就是说在泛型使用过程中...,数据类型被设置为一个参数,在使用时再从外部传入一个数据类型;而一旦传入了具体的数据类型后,如果传入变量(实参)的数据类型和形参的数据类型不匹配,编译器就会直接报错。...super T>:被称作有下界的通配符 在引入泛型通配符之后,我们便得到了一个在逻辑上可以表示为某一类型参数范围的父类引用类型 七、进阶用法 公司架构大佬给我出了一道题:我希望执行 execute()
类型通配符 使用类型通配符 类型通配符的上限 类型通配符的下限 泛型形参的上限 泛型方法 带泛型的返回值 总结 前言 Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制...当创建了带泛型声明的接口、类之后,可以为该接口或者类创建实现类,或者是派生子类,当使用这些接口、父类时不能再包含形参:例如下面的做法就是错误的: //定义类A继承Apple类,Apple类不能跟泛型形参...A extends Apple{} 调用方法时必须为所有的数据形参传入参数值,与调用方法不同的是,使用接口、类时也可以不为泛型形参传入实际的参数参数,即下面的代码也是正确的 //使用Apple...java泛型不仅允许在通配符上使用上限,而且可以在定义泛型形参的时候设定上限,表示传给该泛型形参必须是该类上限类型,要不就是该上限类型的子类,如下所示: public class Apple在一种更极端的情况下,程序需要为泛型设置多个上限(至少有一个父类上限,可一个有多个接口上限),表明该泛型形参必须是父类的子类(父类也行),并且实现多个上限的接口,如下所示: //表明T类型必须是Number
() 方法中,其形参为 ArrayList 我们已经讨论了和作为方法参数的作用。实际上,Java 的泛型还允许使用无限定通配符,即只定义一个?符号。 ...即只可以取值,不可以设值。 (2)对于,编译器将只允许写操作,不允许读操作。即只可以设值(比如 set 操作),不可以取值(比如 get 操作)。...比如对于 List 而言,不允许的写操作有 add 方法,因为它的方法签名是boolean add(E e);,此时这个形参 E 就变成了一个涉及了通配符的类型参数;而不允许的读操作有 get 方法,因为它的方法签名是...E get(int index);,此时这个返回值 E 就变成了一个涉及了通配符的类型参数。
泛型,即“参数化类型”。一提到参数,最熟悉的就是定义方法时有形参列表,普通方法的形参列表中,每个形参的数据类型是确定的,而变量是一个参数。...在调用普通方法时需要传入对应形参数据类型的变量(实参),若传入的实参与形参定义的数据类型不匹配,则会报错。 那参数化类型是什么?...以方法的定义为例,在方法定义时,将方法签名中的形参的数据类型也设置为参数(也可称之为类型参数),在调用该方法时再从外部传入一个具体的数据类型和变量。...泛型类的使用 在创建泛型类的对象时,必须指定类型参数 T 的具体数据类型,即尖括号 中传入的什么数据类型,T 便会被替换成对应的类型。...比如对于 List 而言,不允许的写操作有 add 方法,因为它的方法签名是boolean add(E e);,此时这个形参 E 就变成了一个涉及了通配符的类型参数; 而不允许的读操作有 get 方法
从代码上讲,就是对类型实现了参数化。 3.引出泛型 如果我们创建一个数组,可以存储所有基本类型的数据,纳闷该如何实现呢 1....2.在set方法存入数据时,因为指定了类型为String类型,所以不能放入其他类型,否则就会报错。 3.在实例化时加入尖括号里面的内容是包装类型。 4.泛型小结 1....泛型目前为止的优点:数据类型参数化,编译时自动进行类型检查和转换 5.泛型擦除机制 即编译的时候将所有的T擦除为Object,运行的时候没有泛型这样的概念,简单来说,泛型的擦除机制只存在于编译当中...Number 的子类型 MyArray l2 ; // 编译错误,因为 String 不是 Number 的子类型 这里如果没有上界,可以视为...,也不用加尖括号声明类型形参,因为在编译时,会自动匹配所对应的类型。
、接口、方法时使用类型形参,这个类型形参(或叫泛型)将在声明变量、创建对象、调用方法时动态地指定(即传入实际的类型参数,也可称为类型实参 ) 。...// 定义接口时指定了 一个泛型形参,该形参名为 E public interface List{ // 在该接口里....// 定义该接口时指定了两个泛型形参,其形参名为 K 、 v } public interface Map{ // 在该接口里 K 、 V 完全可以作为类型使用 Set...J ava 泛型不仅允许在使用通配符形参 时设定上限,而且可以在定义泛型形参 时设定 上限 ,用于表示传给该泛型形参的实际类型要么是该上限类型 ,要么是该上限类型的子类。...在一种更极端的情况下,程序需要为泛型形参设定多个上限 (至多有一个父类上限,可以有多个接口上限),表明该泛型形参必须是其父类的子类(是父类本身也行),并且实现多个上限接口。
一、泛型概述 1、定义: 所谓泛型,就是允许在定义类、接口、方法时使用类型形参,这个类型形参(或叫泛型)将在声明变量、创建对象、调用方法时动态地指定(即传入实际的类型参数,也可称为类型实参)。...假设现在需要定义一个方法,该方法里有一个集合形参,集合形参的元素类型是不确定的,那应该怎样定义呢?..."+c+"上"); } } 上面定义了三个形状类,其中Shape是一个抽象父类,该抽象父类有两个子类:Circle和Rectangle。...4、泛型方法: 前面介绍了在定义类、接口时可以使用泛型形参,在该类的方法定义和成员变量定义、接口的方法定义中,这些泛型形参可被当成普通类型来用。...在另外一些情况下,定义类、接口时没有使用泛型形参,但定义方法时想自己定义泛型形参,这也是可以的,Java5还提供了对泛型方法的支持。
一、泛型概述 1、定义: 所谓泛型,就是允许在定义类、接口、方法时使用类型形参,这个类型形参(或叫泛型)将在声明变量、创建对象、调用方法时动态地指定(即传入实际的类型参数,也可称为类型实参)。...假设现在需要定义一个方法,该方法里有一个集合形参,集合形参的元素类型是不确定的,那应该怎样定义呢?...()方法的形参类型是List,而List并不是List的子类型,因此,下面代码将引起编译错误。...4、泛型方法: 前面介绍了在定义类、接口时可以使用泛型形参,在该类的方法定义和成员变量定义、接口的方法定义中,这些泛型形参可被当成普通类型来用。...在另外一些情况下,定义类、接口时没有使用泛型形参,但定义方法时想自己定义泛型形参,这也是可以的,Java5还提供了对泛型方法的支持。
1、泛型的概述: 1.1 泛型的由来 根据《Java编程思想》中的描述,泛型出现的动机: 有很多原因促成了泛型的出现,而最引人注意的一个原因,就是为了创建容器类。...: 方法声明中定义的形参只能在该方法里使用,而接口、类声明中定义的类型形参则可以在整个接口、类中使用。...//定义接口时指定了一个类型形参,该形参名为Epublic interface List extends Collection { //在该接口里,E可以作为类型使用 public...E get(int index) {} public void add(E e) {} } //定义类时指定了一个类型形参,该形参名为Epublic class ArrayList extends...在静态方法、静态初始化块或者静态变量的声明和初始化中不允许使用类型形参。
而假如我们在创建类型的时候也为其指定参数,这个参数又是个类型,那么我们就称之为泛型。 那么泛型的作用和意义是什么?使用泛型能够像传递参数一样传递类型,同时保证运行时的类型安全。...声明方法的时候为其指定了类型参数T。 } } 上例简单展示了泛型的定义,上面的T可以传入任何类型进行表示,这就相当于一个入参,只不过这个入参是个类型而已。...PECS的全称可以理解为Producer-Extends-Consumer-Super,即其描述了子类限制符和父类限制符的使用原则。 1.错误,需要Array类型,但是传入的是Array类型 } 上面的代码又复现了经典的问题,即泛型类型是不变因子,即Array不是Array的子类,为什么要这么限制?...道理和上面一样,kotlin认为我们有可能会对from进行写操作,比如我们在copy中为from中的一个元素赋值了一个字符串(虽然我们按正常逻辑不会这么写,我们只需要完成copy的功能就行,但是kotlin
,可通过继承的get/set方法进行访问 如图所示: 3、在Java 中,继承的关键字用的是“extends”,即子类不是父类的子集,而是对父类的“扩展” 子类在继承父类以后,还可以定义自己特有的方法,..., 结合②,结论:在构造器的首行,“this(形参列表)” 和 "super(形参列表)"只能二选一 ④ 如果在子类构造器的首行既没有显示调用"this(形参列表)",也没有显式调用"super(形参列表...)", 则子类此构造器默认调用"super()",即调用父类中空参的构造器 ⑤ 由③和④得到结论:子类的任何一个构造器中,要么会调用本类中重载的构造器,要么会调用父类的构造器。 ...⑥ 由⑤得到:一个类中声明有n个构造器,最多有n-1个构造器中使用了"this(形参列表)“,则剩下的那个一定使用"super(形参列表)” 开发中常见错误: 如果子类构造器中既未显式调用父类或本类的构造器...答案:是的 问题:创建子类的对象时,内存中到底有几个对象? 答案:只有一个对象!
可变参数可以和普通类型的参数一起放在形参列表,但是必须保证可变参数在最后,否则编译都会报错,更别提使用了 一个形参列表中只能有一个可变参数,并且需要放到参数列表的最后 构造方法 需求 前面的都是先创建好一个对象之后...,再给他的年龄赋值 现在要求:在创建人类的对象时,直接指定这个对象的年龄和姓名,一次完成 构造器的主要目的:完成对新对象的初始化,而不是创建新对象 基本语法 [修饰符] 方法名(形参列表){...类型的,不能由其它类访问,所以p1.age本身就是错误的 上面就是set方法,又去赋值,是错误的 在调用set方法时,只需要去传参即可 this关键字 目的 构造器的形参,如果能够直接写成属性名...可以继续继承,下一层会包含上一层的所有属性 我的理解:extends相当于复制了父类中的所有属性和方法 继承细节 第一:私有属性不能直接在子类中访问 子类继承了所有的属性和方法...子类必须调用父类的构造器,完成父类的初始化 也就是说,在main函数中实例化子类时,是首先进行父类的构造器调用,然后再进行子类的构造器调用(初始化) 第三:在父类中没有默认的无参构造器时
,间接也继承了A类属性/方法,也可以自定义此类的特有属性/方法(用于内部访问) }; 抽象类是不能new 实例的,即这里就是在表示一个 匿名类了; // 创建出对象a 就是这个匿名类的实例了,即这个类是没有名字的借用了父类名...有意义的 名字 可以 方便调用 注意:命名规范 (骆驼命名法) 参数列表: //方法()括号中放参数类型, 用于指定方法内运行 需要使用的变量/数据进行操作; 又分为形参 实参; 形参: 出现在方法定义时...方法set内部进行判断; 而之后我们还是可以通过: 对象.属性 进行赋值所以一般给其设置: private(私有属性) 定义: 隐藏对象(类)属性,和实现细节,仅对外公开接口(方法); 控制在程序中属性的读取...get(读) 和修改set(写) 的访问级别; set(参数){ …… }; //封装通过set 给,类对象属性进行赋值操作,当然也可以对齐内部进行判断使其只能赋:合法值: 年龄不能是 负数;...// Final可以在方法内 也可以作为形参使用! `估计不常用!
c#的多台方法,大体上和c++的类似,但是有点区别的,我这里刚刚初学,因此把重点记录下。 多态是同一个行为具有多个不同表现形式或形态的能力。 多态性意味着有多重形式。...多态就是同一个接口,使用不同的实例而执行不同操作 1、静态多态性 在编译时,函数和对象的连接机制被称为早期绑定,也被称为静态绑定。C#提供了两种技术来实现静态多态性。...2、动态多态性 2.1抽象类之abstract C#允许您使用关键字abstract创建抽象类,用于提供接口的部分类的实现。当一个派生类继承自该抽象类时,实现即完成。...* 说白了,子类调用Draw()的使用是调用了基类的Draw().并没有实现多态的功能 如果使用上面的宏定义 输出是 画一个长方形 执行基类的画图任务 画一个三角形 执行基类的画图任务 画一个圆形...注:继承类中的重写虚函数需要声明关键字 override,在方法参数传入中写(类名 形参名)例如 public void CallArea(Shape sh),意思是传入一个 shape 类型的类。
形参就位于定义函数的括号内 实际参数(实参):有实际的数值,位于调用函数时函数名后面的括号内 函数在实现参数和调用参数的过程叫做:传递参数(传参) 5.4 参数的分类 5.4.1 必须参数 就是必须按照正确的顺序来将实际参数传入到函数中...def hello(name): print(f'hello,我叫{name}') hello('小明') 形参和实参的数量要一致 注意函数参数的位置,实参和形参必须一一对应 5.4.2 默认参数...封装是将数据和操作封装在一个对象中,隐藏对象的内部实现细节,只暴露必要的接口给外部访问。继承是通过继承父类的属性和方法,来创建一个新的子类,子类可以重写父类的属性和方法,从而实现更加灵活的功能。...不需要手动调用 类中的每个方法在创建的时候基本上都自动定义了一个self参数 self:用来表示对象本身的 class People: # 类属性(类属性是所以对象共同的属性) age...如果父类的某个属性或方法也在子类中定义了,那么子类会重写父类的属性或方法,这样子类可以更好地针对自己的特定要求来实现相应的功能。
,它没有方法体,即方法实现代码为空,比如abstract public void fun(); 抽象方法一般在子类中进行实现,它就好像是在说:我不写代码,我只是声明一个方法名,剩下的交给我的子孙后代(继承类...)去做 抽象类有一个很重要的特点:抽象类可以没有抽象方法,但是如果一个类有抽象方法,那么这个类肯定是抽象类 为什么会有抽象类 解耦,使代码结构更加清晰 因为抽象类不能被直接创建为对象,它只是作为一个通用接口来供别人实现和调用...继承(Inheritance) 如果子类继承了父类,那么子类就可以复用父类的方法和属性,并且可以在此基础上新增方法和属性 这里要注意的一点是:Java是单继承语言,即每个类只能有一个父类 这里还要普及一个常识...多态(Polymorphism) 字面理解,就是多种形态,在Java中,多态指的是,一个类可以有多种表现形态 多态主要是 用来创建可扩展的程序 像我们上面提到的继承就是属于多态的一种 还有一种就是接口(...场景很多,这里说两个最常用的 场景一:方法的参数,即方法定义时,父类作为方法的形参,然后调用时传入子类作为方法的实参 场景二:方法的返回值,即方法定义时,父类作为方法的返回值,然后在方法内部实际返回子类
,它没有方法体,即方法实现代码为空,比如abstract public void fun(); 抽象方法一般在子类中进行实现,它就好像是在说:我不写代码,我只是声明一个方法名,剩下的交给我的子孙后代(继承类...)去做 抽象类有一个很重要的特点:抽象类可以没有抽象方法,但是如果一个类有抽象方法,那么这个类肯定是抽象类 为什么会有抽象类 解耦,使代码结构更加清晰 因为抽象类不能被直接创建为对象,它只是作为一个通用接口来供别人实现和调用...继承(Inheritance) 如果子类继承了父类,那么子类就可以复用父类的方法和属性,并且可以在此基础上新增方法和属性 这里要注意的一点是:Java是单继承语言,即每个类只能有一个父类 这里还要普及一个常识...多态(Polymorphism) 字面理解,就是多种形态,在Java中,多态指的是,一个类可以有多种表现形态 多态主要是 用来创建可扩展的程序 像我们上面提到的继承就是属于多态的一种 还有一种就是接口...场景很多,这里说两个最常用的 场景一:方法的参数,即方法定义时,父类作为方法的形参,然后调用时传入子类作为方法的实参 场景二:方法的返回值,即方法定义时,父类作为方法的返回值,然后在方法内部实际返回子类