一、多态的前提与体现
-
有继承/实现关系
-
有方法重写
-
有父类引用指向子类对象,如在使用过程中有这样的对象,也可以说以多态的形式创建对象
父类 a = new 子类()
二、多态中成员访问特点
成员变量:编译看左边、执行看左边
成员方法:编译看左边、执行看右边
例如在这个例子中
//父类
public class Animal{
public int age = 40;
public void eat(){
System.out.println("父类中方法");
}
}
//子类
public class Cat extends Animal{
public int age = 20;
public int weight = 10;
//方法重写
@Override
public void eat(){
System.out.println("子类中方法");
}
public void Playgame(){
System.out.println("猫捉迷藏");
}
//测试类
public class Demo{
public static void main(String[] args){
//父类引用指向子类对象
Animal a = new Cat();
System.out.println(a.age);
//如果输入a.weight将会报错
a.eat();
}
}
运行结果将会是
age = 40 子类中方法
多态的好处:
定义方法的时候,使用父类型作为参数,在使用的时候,再使用不同的子类,可简化操作,如:
父类为Animal,需要用到不同的具体动物时,如定义动物中有方法喝水、吃饭,则子类中不同动物都可以通过多态来简洁的实现各自的喝水、吃饭方法中的不同。但要记住,利用多态时不能使用子类中特有的方法,但可利用转型来改变。
三、转型
在上方代码例子中,如果希望能使用子类中也有方法Playgame()则可以在测试类中做出如下改变:
//测试类
public class Demo{
public static void main(String[] args){
//父类引用指向子类对象
Animal a = new Cat();
a.eat();
//向下转型
Cat c = (Cat)a;
//现在即可使用Cat类中特有方法
c.Playgame();
}
}
抽象类
一个没有方法体的方法应该定义为抽象方法,而类中如果有抽象方法,该类必须定义为抽象类
抽象类的定义与特点
//抽象类
public abstract class Animal{
//抽象方法
public abstract void eat();
}
抽象类特点:
-
抽象类中可以没有抽象方法,但抽象方法必须在抽象类中
-
抽象类无法直接创建对象,如在上述类中:
Animal a = new Animal();
是错误的。
但可以通过多态来间接的创建对象。如在上述抽象类Animal基础上:
public class Cat extends Animal{
@Override
public void eat(){
System.out.println("猫吃鱼");
}
}
然后再在测试类使用多态创建对象:
Animal a = new Cat();
3.抽象类的子类要么必须重写完所有抽象类的抽象方法,要么抽象类的子类也是一个抽象类。
抽象类的构造方法
public Animal(){}
用于子类访问父类数据的初始化,存疑?
接口一种公共的规范标准
接口也是抽象的,不能直接创建对象,但可以与抽象类类似的使用多态来间接创建对象
接口的定义
public interface 接口名 {}
类实现接口
//与继承相区别
public class 类名 implements 接口名{}
接口的成员特点
-
在接口中,成员变量都默认被static final修饰,也就是看错常量,我认为因为接口时一个规范,所有其中的变量自然也就是不可修改的
-
接口中没有构造方法,当一个类实现接口时,其中如果存在super(),是因为每个类都会有默认的父类Object()
-
接口中也不能有非抽象方法。写了抽象方法后,然后后边再通过多态来重写实现,所以在接口中的方法都默认带有public abstract
-
一个类可以在继承一个类的基础上实现多个接口
public class 子类 extends 父类 implements 接口1,接口2,接口3{} -
接口与接口可以单继承与多继承
单继承:
public interface 接口1 implements 接口2{}多继承:
public interface 接口1 implements 接口2,接口3,接口4{}
当抽象类、接口作为形参时,都是需要对象,而抽象类与接口不能直接创建对象,所以需要使用多态的形式来辅助创建对象,以此成功创建形参
内部类:定义格式:
public class 类名(外部类){
修饰符 class 类名{
}
}
-
内部类可以直接访问外部类成员,包括私有
-
外部类想要访问内部类的成员则必须要通过在外部类中创建内部类的对象来访问
创建内部类对象:
-
针对内部类为 public时
外部类.内部类 对象名 = new 外部类().new 内部类();
-
若内部类为private,则只能通过外部类来访问内部类
局部内部类:
没有修饰符,不能从外界直接访问,只能通过外部类中创建对象来进行访问
public class 类名(外部类){
class 类名{
}
}
匿名内部类
局部内部类的一种特殊形式
因为其本质为对象,所以可以这样来调方法:
piblic class Outer{
public void method(){
new Inter(){
@Override
public void show(){
}
}.show();
}
}
异常
概述
JVM默认处理方案
如果程序出现了问题,我们没有做任何处理,最终JVM会做默认的处理,会把异常的名称,异常原因及异常出现的位置等信息输出在了控制台,同时程序停止执行
异常处理
try...catch...
try{
可能出现异常的代码;
}catch(异常类名 变量名){
异常的处理代码;
}
程序从try里面的代码开始执行,出现异常,会自动生成一个异常类对象,该异常对象被提交给Java运行时系统,当Java运行时系统接收到异常对象时,会到catch中去找匹配的异常类,找到后进行异常的处理,执行完毕之后,程序还可以继续往下执行。
try...throws...
编译时异常必须要进行处理,两种方案:try……catch……或者throws,如果采用throws这种方案,将来谁调用谁处理
格式:throws 异常类名;
public class ExceptionDemo03 {
public static void main(String[] args) {
System.out.println("开始");
// method();
try {
method2();//直接选中method2然后Alt+Enter即可出现try……catch……
} catch (ParseException e) {
e.printStackTrace();
}
System.out.println("结束");
}
//编译时异常
public static void method2() throws ParseException {
String s = "2048-08-09";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date d = sdf.parse(s);
System.out.println(d);
}
//运行时异常
public static void method() throws ArrayIndexOutOfBoundsException{
int[] arr = {1, 2, 3};
System.out.println(arr[3]);
}
}
-
所有的RuntimeException类及其子类被称为运行时异常,其他的异常都是编译时异常
编译时异常:必须显示处理,否则程序就会发生错误,无法通过编译
运行时异常:无需显示处理,也可以和编译时异常一样处理
自定义异常
格式:
public class 异常类名 extends Exception{
无参构造
带参构造
}
-
throws:用在方法声明后面,跟的是异常类名;表示抛出异常,由该方法的调用者来处理;表示出现异常的一种可能性,并不一定会发生这些异常
throw:用在方法体内,跟的是异常对象名;表示抛出异常,由方法体内的语句处理;执行throw一定抛出了某种异常
泛型
提供了编译时类型安全检测机制,该机制允许在编译时检测到非法的类型
它的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数
参数化类型:将类型由原来的具体的类型参数化,然后在使用/调用时传入具体的类型
这种参数类型可以用在类、方法和接口中,分别被称为泛型类、泛型方法、泛型接口
泛型定义格式:
<类型>:指定一种类型的格式,这里的类型可以看成是形参
<类型1,类型2……>:指定多种类型的格式,多种类型之间用逗号隔开,这里的类型可以看成是形参
将来具体调用时候给定的类型可以看成是实参,并且实参的类型只能是引用数据类型
泛型类
格式:修饰符 class 类名<类型>{}
public class Generic{} 此处的T可以随便写为任意标识,常见的如T、E、K、V等形式的参数常用于表示泛型 public class Genric { private T t; public T getT() { return t; } public void setT(T t) { this.t = t; } } public class GenericDemo { public static void main(String[] args) { Student s=new Student(); s.setName("cyx"); System.out.println(s.getName()); Teacher t=new Teacher(); t.setAge(30); System.out.println(t.getAge()); System.out.println("--------"); Genric g1=new Genric<>(); g1.setT("cyx"); System.out.println(g1.getT()); Genric g2=new Genric<>(); g2.setT(20); System.out.println(g2.getT()); } }
PS:此处的T可以随便写为任意标识,常见的如T、E、K、V等形式的参数常用于表示泛型
泛型方法
格式:修饰符<类型>返回值类型方法名(){}
泛型接口
格式:修饰符 interface 接口名<类型>{}
类型通配符
为了表示各种泛型list的父类,可以使用类型通配符
-
类型通配符:<?>
List>:表示元素类型未知的list,它的元素可以匹配任何的类型
这种带通配符的List仅表示它是各种泛型的父类,并不能把元素添加到其中
-
如果不希望List>是任何泛型的父类,只希望它代表某一类泛型List的父类,可以使用类型通配符的上限
类型通配符:
List:它表示的类型是Number或者其子类型
-
除了可以指定类型通配符的上限,也可以指定类型通配符的下限
类型通配符下限:
List:它表示的类型是Number或者其父类型 import java.util.ArrayList; import java.util.List;
可变参数
可变参数又称参数个数可变,用作方法的形参出现,那么方法参数个数就是可变的了
格式:修饰符 返回值类型 方法名(数据类型……变量名){}
集合框架
集合类的特点:提供一种存储空间可变的存储模型,存储的数据容量可以发生变化
ArrayList
ArrayList
在出现E的地方我们使用引用数据类型替换即可
eg:ArrrayList,ArrayList
ArrayList构造方法和添加方法
ArrayList集合常用方法
import java.util.ArrayList;
public class ArrayListDemo02 {
public static void main(String[] args) {
ArrayList array=new ArrayList();
array.add("hello");
array.add("world");
array.add("java");
//public boolean remove(Object o):删除指定的元素,返回删除是否成功
//System.out.println(array.remove("world"));
//System.out.println(array.remove("javaee"));
//public E remove(int index):删除指定索引处的元素,返回被删除的元素
//System.out.println(array.remove(1));
//System.out.println(array.remove(3));//IndexOutOfBoundsException
//public E set(int index,E element):修改指定索引处的元素,返回被修改的元素
//System.out.println(array.set(1,"javaee"));
//System.out.println(array.set(3,"javaee"));//IndexOutOfBoundsException
//public E get(int index):返回指定索引处的元素
// System.out.println(array.get(0));
// System.out.println(array.get(1));
// System.out.println(array.get(2));
// System.out.println(array.get(3));//IndexOutOfBoundsException
//public int size():返回集合中的元素的个数
System.out.println(array.size());
System.out.println("array"+array);
}
}
Collection
是单例集合的顶层接口,它表示一组对象,这些对象也称为Collection的元素
JDK不提供此接口的任何直接实现,它提供更具体的子接口(如Set/List)实现
创建Collection集合的对象:多态的方式
具体的实现类ArrayList
import java.util.ArrayList;
import java.util.Collection;
public class ArrayListDemo03 {
public static void main(String[] args) {
//创建Collection集合的对象
Collection c=new ArrayList();
//添加元素:boolean add(E e)
c.add("hello");
c.add("world");
c.add("java");
System.out.println(c);
}
}
Collection集合常用方法
Collection集合的遍历
Iterator:迭代器,集合的专用遍历方式 Iteratoriterator():返回此集合中元素的迭代器,通过集合的iterator()方法得到 迭代器是通过集合的iterator()方法得到的,所以我们说它是依赖于集合而存在的
Iterator中的常用方法:
E next():返回迭代中的下一个元素
boolean hasNext():如果迭代具有更多元素,则返回true
集合的使用步骤
List集合概述和特点
List集合概述称为有序集合(也称为序列),用户可以精确控制列表中每个元素的插入位置,用户可以通过整数索引访问元素,并搜索列表中的元素与Set集合不同,列表通常允许重复的元素其特点为有序(存储和取出的元素顺序一致)可重复(存储的元素可以重复)
List集合特有方法
ListIterator
列表迭代器通过list集合的listIterator()方法得到,所以说它是list集合特有的迭代器
用于允许程序员沿任一方向遍历列表的列表迭代器,在迭代期间修改列表,并获取列表中迭代器的当前位置
常用方法: E next():返回迭代中的下一个元素 boolean hasNext():如果迭代具有更多元素,则返回true E previous():返回列表中的上一个元素 boolean hasPrevious():如果此列表迭代器在相反方向遍历时具有更多元素,则返回true void add(Ee):将指定的元素插入列表
增强for循环
强for:简化数组和Collection集合的遍历
实现Iterable接口的类允许其对象成为增强型for语句的目标
它是JDK5之后出现的,其内部原理是一个Iterator迭代器
格式:for(元素数据类型 变量名:数组或者Collection集合){
//在此处使用变量即可,该变量就是元素
}
数据结构
数据结构是计算机存储、组织数据的方式,指相互之间存在一种或多种特定关系的数据元素的集合
通常情况下,精心选择的数据结构可以带来更高的运行或者存储效率
常见数据结构之栈
数据进入栈模型的过程称为:压/进栈
数据离开栈模型的过程称为:弹/出栈
栈是一种数据先进后出的模型
常见数据结构之队列
数据从后端进入队列模型的过程称为:入队列
数据从前端离开队列模型的过程称为:出队列
队列是一种数据先进先出的模型
常见数据结构之数组
查询数据通过索引定位,查询任意数据耗时相同,查询效率高
删除数据时,要将原始数据删除,同时后面每个数据前移,删除效率低
添加数据时,添加位置后的每个数据后移,再添加元素,添加效率极低
数组是一种查询快,增删慢的模型
常见数据结构之链表
Set
-
Set集合特点:不包含重复元素的集合
-
没有带索引的方法,所以不能使用普通for循环遍历
哈希值
JDK根据对象的地址或者字符串或者数字算出来的int类型的数值
Object类中有一个方法可以获取对象的哈希值
public int hashCode():返回对象的哈希码值
对象的哈希值特点:
同一个对象多次调用hashCode()方法返回的哈希值是相同的
默认情况下,不同对象的哈希值是不同的,而重写hashCode()方法,可以实现让不同对象的哈希值相同
HashSet集合概述和特点
HashSet集合特点:
-
底层数据结构是哈希表
-
对集合的迭代顺序不作任何保证,也就是说不保证存储和取出的元素顺序一致
-
没有带索引的方法,所以不能使用普通for循环遍历
-
由于是Set集合,所以是不包含重复元素的结婚
-
HashSet集合存储元素:要保持元素唯一性,需要重写hashCode()和equals()
map
Interface MapK:键的类型;V:值的类型
-
将键映射到值的对象;不能包含重复的键;每个键可以映射到最多一个值
-
创建Map集合的对象
-
多态的方式
-
具体的实现类HashMap
基本功能
获取功能



