前言
在上章里我们讲解了Java是什么、Java的语言基础、Java的逻辑控制、Java方法、Java数组和类与对象等,而本章主要讲解的是泛型的认知、各种内部类讲解、面向对象编程。
一.泛型的认知
什么是泛型?泛型:当你无法明确使用什么数据类型时,我们可以使用一个字母 T代替数据类型。泛型同样可以涉及到类,例如泛型类,而大多数时候会使用在数据结构当中。
💖泛型类
泛型类的语法格式:
第一种:class 泛型类名称<类型形参列表> {
// 这里可以使用类型参数
}
第二种: class 泛型类名称<类型形参列表> extends 继承类/* 这里可以使用类型参数 */ {
// 这里可以使用类型参数
}
注:泛型只能接受类,所有的基本数据类型必须使用包装类!
代码示例:
public class Text1<T> { public T age; public static void main(String[] args) { Text1<Integer> fw=new Text1<>() fw.age=20; } }
💖泛型数组
数组也可以使用泛型,但是在编译过程当中,会把T转换为Object,因此我们无法确认是什么数据类型,因此需要通过强制转换,所以我们正确的格式:T [ ] array=(T[ ]) new Object[大小];
💖泛型的上界
泛型可代表任何数据类型,同样也可以为类。
例: public class MyArray<E extends Number> {
... //相当于 < T >
}
解析:Number是一个类或者接口,因此E为Number的子类,因此这个泛型有了限制,范围为Number的子类
注:无下界哦
💖泛型的方法
泛型的方法只适用于静态方法,而其它方法不需要。
静态方法使用泛型: public static <E> void 函数名(形数){ }
二.内部类讲解
内部类分为4种,实例内部类、静态内部类、局部内部类、匿名内部类。
实例内部类
public class 外部类名 { //实例内部类 class InnerClass{ //代码 // public static int date=60;错误,无法定义静态成员变量 public static finally int date=60 //finally修饰,为常量 } public static void main(String[] args) { //实例化内部类 外部类名 kk = new 外部类名(); 外部类名.InnerClass fw = new 外部类名().new InnerClass(); fw.textInner(); //输出结果为:textInne } }
- 实例内部类:在类的内部里创建一个新的类。
- 不可以使用static定义静态成员变量
- 外部类和内部类的变量名不可以相同,若相同,会先访问外部类的
- 外部类的任何成员都可以在实例内部类方法中直接访问。
- 实例化内部类:先实例化外部类,接着语法:外部类.内部类 对象名=new 外部类().new 内部类()
- 在内部类中调用外部类的成员,调用方法:外部类名.this.同名成员。
静态内部类
就是在实例内部类cclass前使用了static修饰,相当于外部类的一个静态成员,可以访问外部类的静态成员和方法,非静态无法访问。静态内部类可以直接实例化 不需要依附于外部类,语法格式:内部类名 变量名=new 内部类(); 在该内部类中可以声明静态成员也可以声明非静态成员
局部内部类
在方法体中定义的内部类,不能被访问修饰符public、private和静态修饰符等修饰,作用域也仅限方法中,可以直接访问方法中的属性
匿名内部类
interface Shape{ void draw(); } public class Text3 { public static void main(String[] args) { int area=20; new Shape(){ //需要重写内部方法 public void draw() { // area=50; 无法修改,一旦修改无法访问了。 System.out.println("正方形面积:"+area); } }.draw(); //调用draw(); }
不能定义任何静态成员、方法和类,使用的是接口,匿名内部类一定是在new的后面,用其隐含实现一个接口或实现一个类,并且不可修改匿名内部类外的变量
三.了解异常
异常分为2种,RuntimeException(运行时异常)和受检类异常。而一般而言,运行时异常就是代码问题,可以避免,但是受检类异常则是指I/O异常、网络地址不能打开、文件未找到等。因此无法避免,我们需要使用try-catch-finally语句。
语法格式: try{
//可能发生异常的语句
}
catch(异常类名 形参名 ){
//对异常处理的语句
}
finally{
//无论是否存在异常,都要运行,且可以省略
}
当然除了以上的那种方法,还有一种不负责的方法,抛出,当有异常发生时,就丢了,当着没看见进行执行。关键字throw、throws
throw
根据实际情况,在可能发生异常的语句前加 throw。
throws
在方法的头部声明,抛出异常,从而使该方法内不需要在意这个异常(睁眼瞎).
语法格式:public void fun() throws 异常类{ ....... }
throw和throws的区别,简单而言就是,前者是个人假装没有发现问题,不想惹事上身。后者是上头领导通知,不要在意这个问题
四.面向对象编程
java基础知识点中最重要的便是面向对象编程。面向对象编程包含学会包、继承、多态、抽象、接口的知识点。
💖包
包可以存放多种类。包有2种,一种是自己定义的,另一种是Java已经提高的。例如java.util包,若想使用包中的类,需要导包,有2种形式:
- 准确无误误的引入对应包的类,例如 java.util.Date。引入了java.util包的Date类。
- 引入对应包的所有类,例如java.util.*。这个*号代表了java.util类下的所有类
将类放入包中
先创建一个包,然后在包内创建新的类名。
如果一个类没有 package 语句, 则该类被放到一个默认包中
包名规则
包名需要尽量指定成唯一的名字, 通常会用公司的域名的颠倒形式(例如 com.tq02.demo1 ).
包名要和代码路径相匹配. 例如创建 com.tq02.demo1 的包, 那么会存在一个对应的路径 com/tq02/demo1 来存储代码
💖继承
类与类之间可以存在父子关系的哦,一个叫父类、一个叫子类。子类可以拥有父类所有的public字段和方法。也就是可以继承父亲愿意给儿子的,而不愿意给的则用private封装起来。并且子类也可以通过super得到父类的实例。继承关键字:extends
而在继承当中,我们需要熟练掌握访问修饰符,不同的访问修饰符不同的意义。
class Animal { public String name; public Animal(String name) { this.name = name; } public void eat(String food) { System.out.println(this.name + "正在吃" + food); } } class Cat extends Animal { public Cat(String name) { // 使用 super 调用父类的构造方法. super(name); } } class Bird extends Animal { public Bird(String name) { super(name); } public void fly() { System.out.println(this.name + "正在飞 ︿( ̄︶ ̄)︿"); } } public class Test { public static void main(String[] args) { Cat cat = new Cat("小黑"); cat.eat("猫粮"); Bird bird = new Bird("圆圆"); bird.fly(); }
💖多态
从一定角度来看,封装和继承几乎都是为多态而准备的。因为多态的存在,需要三个条件
1、需要继承 2、需要重写 3、父类引用指向子类对象
多态主要的技术有:向上转型、向下转型、动态绑定、方法重写。
动态绑定
即方法与方法的主体在运行时才进行绑定。例如,当父类和子类拥有一个同名的方法(remove),那么定义了an.remove(),remove方法的调用主体是an,但是an只有调用时,才能知道是实例化了哪个类。而这便是动态绑定。例如之后讲解的向上转型,调用的方法应该是子类的还是父类的。
向上转型
父类对象通过子子类对象去实例化,实际上就是对象的向上转型。向上转型是不需要进行强制类型转换的,但是向上转型会丢失精度。并且实例化的对象只能访问父类中存在的方法和属性,若是子类重写了,则调用子类的方法
语法格式:父类 对象名=new 子类();
向下转型
并不是所有的对象都可以向下转型,只有当这个对象原本就是子类对象通过向上转型得到的时候才能够成功转型,在向下转型前,通过instanceof
判断某对象是否是某类的实例。换句话说,就是先向上转型,然后再强制类型转换回来。
方法重写
子类中方法名和父类相同,修饰符 返回值类型 方法名(参数列表) 要完全一致,也就是方法体不一样,而实例化对象之后不再是使用父类的方法了,而是使用子类的方法。父类被static、private final修饰的方法不能被重写。
💖抽象类和接口
抽象
存在的意义就是为了被继承,当所有的子类都要重写父类的某个方法时,父类的方法可以为抽象方法,直接声明,不需要结构体。
定义方法:
public abstract 类名{
String name;
public abstract void 方法名();
}
接口
接口是为了弥补代码无法多继承,只能单继承的问题,又名为完全抽象类,也就是说接口内的函数都不存在结构体,并且所有的方法都是public和抽象的,而且在代码当中可以省略不写,接口无法被实例化哦,且一个类可以拥有多个接口。
定义方法: public interface 接口名{ }
使用接口: class 类名 implements 接口名{ 方法体 };
二者之间的区别:
- 抽象类可以包含非抽象方法,而接口只能包含抽象方法。
- 类只能继承一个抽象类,但可以实现多个接口。
- 抽象类可以有构造方法,而接口不能有构造方法。
- 抽象类可以有成员变量,而接口只能有常量。
- 抽象类的方法可以有public、protected和default访问修饰符,而接口的方法只能有public访问修饰符。
- 抽象类的子类必须实现所有抽象方法,而实现接口的类必须实现所有接口中的方法。
- 抽象类可以有普通方法,而接口不能有普通方法。
目前为止,javaSE的复习就到此结束了,如果对你有用,期待你的留言哦!!!
------------懒惰的tq02