一 . 多态
1 . 概念 :
一个事物体现的不同形态
2 . 多态的前提条件
(1)必须存在继承关系,如果没有继承关系就没有多态
(2)必须存在方法重写,需要将父类的功能覆盖掉,让子类完成自己的功能. (强制重写)
(3)需要存在"父亲引用指向子类对象"
格式
父类名 对象名 = new 子类名(); --------->(向上转型)用的是父类的东西
3 . 多态中的成员访问特点
(1)成员变量
编译看左,运行看左.------如果编译通过了,说明父类中存在变量,运行看左,使用父类的东西
(2)成员方法---非静态的
编译看左,运行看右------因为子类出现了父类一模一样的方法,覆盖父类的方法
(3)静态的成员方法
和类相关,被称为---类成员,随着类的加载而加载,访问通过类名访问
(4)构造方法
因为存在继承关系,存在无参构造/有参构造,都需要父类先初始化,然后才是子类,分层初始化
4 . 多态的好处
(1)可以提高代码的复用性<继承保证的>
(2)可以提高代码的扩展性<多态保证---父类引用指向子类对象>
5 . 多态的弊端
向上转型-------使用的是父类的东西,不能访问子类的特有功能
解决方法:
(1)直接创建具体的子类,需要在堆内存中继续开辟空间,消耗内存空间
(2)向下转型-----将父类的引用强转子类引用,节省内存
二 . abstract 关键字 (抽象)
1.抽象的概念 :
在现实中,将比较概括性的食物称为--------抽象的事物
2.书写格式
abstract class 类名 { }
3.抽象类特点
不能创建对象 不能实例化
4.注意事项:
(1)如果一个类中存在抽象方法,那么这个类一定是抽象类
(2)一个抽象类中,不一定都是抽象方法
抽象方法只有方法声明,没有方法体现
权限修饰符 (除过private / fainl / static ) abstract 返回值类型 方法名(形式参数列表)
(3)抽象类的子类如果为抽象类,会存在具体子类,否则没有意义,抽象类的子类为具体类才能创建对象
(4)抽象类的本质:强制子类必须完成的事情
5.抽象类的成员特点
(1)成员变量:既可以是变量,也可以是常量
(2)成员方法:既可以是抽象方法,也可以是非抽象方法
(3)构造方法:存在有参/无参构造方法,分层初始化
三 . 接口
1.概念:
接口就是描述事物本身之外的额外功能-------扩展功能
2.接口格式
inferface 接口名 { }--------------------使用<大驼峰命名法>
实现关键字 implements
3.接口的特点
(1)不能实例化
(2)接口中成员方法:只能是抽象方法,不能有方法体
4.接口注意事项:
(1)接口的子实现类可能是抽象类,抽象类肯定会存在具体的子类,否则没有意义
(2)具体类是通过接口多态进行实例化
5.接口的成员特点
(1)成员变量:只能是常量,存在默认修饰符public static final 可以省略不写
(2)成员方法:只能是抽象方法,存在默认修饰符 publi abstract
(3)构造方法:接口没有构造方法,因为接口只是为了提供事物的额外功能,谁实现了接口,就具备这个功能
6.接口和抽象类的区别
(1)成员区别
接口:
成员变量:只能是常量,存在默认修饰符public static final 可以省略不写
成员方法:只能是抽象方法,存在默认修饰符 publi abstract
构造方法:接口没有
抽象类
成员变量:既可以是常量也可以是变量
成员方法:既可以存在抽象方法,而且抽象方法abstract不能省略,也可以存在非抽象方法;
构造方法:存在无参/有参,继承关系.先让父类初始化,然后再是子类初始化(分层初始化)
(2)关系区别
<1>类与类之间:只支持单继承,不支持多继承,但可以多层继承.
<2>类与接口:实现关系 implements;一个类继承另一个类的同时,可以实现多个接口
<3>接口与接口:继承关系 extends,不仅支持单继承,也可以多继承,也可以多层继承
(3)设计理念的区别
<1>抽象类------存在继承关系extends,体现的是"is a"关系
<2>接口-------存在实现关系implements,提供的是额外功能,体现的是"like a"关系
四 . 方法形式参数问题研究
1.为基本数据类型
实际参数需要传递当前具体基本类型的数据值即可
2.为引用数据类型
<1>具体类:调用该方法,实际参数需要传递的是当前具体对象
<2>抽象类:调用该方法,实际参数需要传递的是当前抽象类的子类对象,抽象类多态完成
<3>接口:调用该方法,实际参数需要传递的是当前接口的子实现类对象,接口多态完成
五 . 方法返回值类型的研究
1.方法返回值为基本数据类型
返回具体的结果: return 结果值;
2.方法返回值为引用数据类型
<1>具体类:如果一个方法的返回值是一个具体类,那么该方法的就需要返回当前类具体对象
<2>抽象类:如果一个方法的返回值是一个抽象类型,那么该方法需要返回当前抽象类的子类对象,使用抽象类多态
<3>接口:如果一个方法的返回值是一个接口类型,接口不能实例化,需要返回当前接口的子实现类对象,使用接口多态
六 . instanceof关键字
instanceof: instanceof是java中的运算符,左边是对象,右边是类,当对象是右边类或者子类所创建对象时,返回 true , 否则返回 false .
(1)类的实例包括本身的实例,以及所有直接或间接子类的实例
(2)instanceof 左边显示声明的类型与右边操作元必须是同种类或存在继承关系,也就是说需要位于同一个继承树,否则会编译错误
if(a instanceof Cat){
System.out.println("这是猫实例");
}else if(a instanceof Dog){
System.out.println("这是狗实例");
七 . 权限修饰符的使用范围
同包下当前类中 同包下子类/无关类 非同包子类 非同包无关类
private Y NO NO NO
默认(default) Y Y NO NO
protected Y Y Y NO
public Y Y Y Y
八 . 带包编译与运行
1.同包下
(1) 对 java 文件进行编译
javac - d . 源文件名称.java eg:javac -d . Demo.java
(2)带包进行运行
java 包名.类名 eg:java com.qf.Demo
2.不同包下
(1)导包
import . 包名 . 类名 ;
(2)编译
javac -d . 源文件名称.java
(3)运行
java 包名.类名
九 . 内部类
1.概念:
在一个类中定义另一个类
2.内部类分类
1 . 成员内部类:在一个类中的成员位置定义的类
(1)成员内部类的特点
成员内部类(非静态)的成员可以访问外部类的成员,包括私有.
(2)直接访问成员内部类成员:非静态
外部类名.内部类名 对象名 = 外部类对象.内部类对象 ;
Outer.Inner oi = new Outer().new Inner() ;
(3)静态成员内部类
无论静态还是非静态成员方法,访问外部类成员变量,外部类成员变量都必须是静态的;
静态的成员内部类随着外部类的加载而加载;
直接访问静态成员内部类中成员方法:
外部类名.内部类名 对象名 = new 外部类名.内部类名;
Outer.Inner oi = new Outer.Inter();
访问静态的成员内部类的静态成员方法:
Outer.Inner.show()
2 . 局部内部类:在一个类的成员方法中定义的类.
<1>局部内部类特点
局部内部类(非静态)的成员可以访问外部类的成员,包括私有.
3 . 匿名内部类
<1>匿名内部类:没有名字的类.
<2>new 接口/类名(){
重写方法()完成业务功能
};
class Outer{
public void method(){
//访问一个
new Inter(){
@Override
public void show() {
System.out.println("show Inter...");
}
}.show() ;
//访问两个个成员方法
public void method(){
Inter inter = new Inter() {//还是接口多态方式:不过子实现类没类名
@Override
public void show() {
System.out.println("show Inter...");
}
@Override
public void show2() {
System.out.println("show2 Integer...");
}
};
inter.show() ;
inter.show2() ;
}
3 . 匿名内部类的本质:就是继承了该抽象类或者实现了该接口子类对象;
4 . 使用场景:匿名内部类使用在方法定义中或者是方法声明上:局部位置中使用
可能方法的形式参数是一个接口/抽象类
可能方法返回值类型是一个接口/抽象类
十 . object 类
object类是超类或基类,所有类的直接或间接父类,位于继承树最顶层;任何类没有书写extends显示继
承某个类,都默认继承object类,否则为间接继承.
1. getclass()
getclass(): 返回引用中存储的实际对象类型,通常用于判断两个引用中实际存储对象类型是否一致.
public final Class getClass():表示正在运行的类的实例,(当前类的字节码文件对象).
getClass()目的就是可以获取正在的运行的类(Class):代表的就是字节码文件对象
Student s1 = new Student() ;
Class c = s1.getClass(); //c: Class com.qf.Student;
public String getName():获取当前类的字符串形式:
c.getNme(); //com.qf.Student 全限定名称
Student s2 = new Student() ;
Class c1 = s1.getClass() ; class com.qf.day15_mytest.Dog
Class c2 = s2.getClass() ; class com.qf.day15_mytest.Dog
System.out.println(s1==s2) ; 分别需要开辟空间
System.out.println(c1==c2) ; 因为类就加载一次,产生的字节码文件就一个
2.hashCode
hashCode方法是返回该对象的十进制哈希码值;把它可以看成是一个"地址值",不是真实意义的地址
值,和哈希表有关,不同的对象,哈希码值不同.
3. toString
返回对象的字符串表示形式(返回对象的成员信息表达式);应该是一个简明扼要的表达,容易让人阅读,建议所有子类覆盖此方法(快捷键: Alt + ins)。
public class Person{
private String name;
private int age;
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
public class Test {
public static void main(String[] args) throws CloneNotSupportedException {
Person p1 = new Person(); 重写前:com.qf.day16_test.Person@1b6d3586
System.out.println(p1); 重写后:Person{name='null', age=0}
//(p1) = (p1.toString)
}
}
4. equals
public boolean equals(Object obj):表示其他对象与此对象是否"相等".
(1)==和equals的区别
<1>==连接基本数据类型: 比较基本数据类型数据值是否相等
==连接引用数据类型: 比较引用数据类型地址值是否相等
<2>equals默认比较地址值是否相同,建议子类重写equals方法,比较成员信息是否相同,重写equals同时还要重写hashCode()方法,保证哈希码值必须一样,才能比较equals. 快捷键:alt+ins
public class Person{
private String name;
private int age;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
if (age != person.age) return false;
return name.equals(person.name);
}
@Override
public int hashCode() {
int result = name.hashCode();
result = 31 * result + age;
return result;
}
}
public class Test {
public static void main(String[] args) throws CloneNotSupportedException {
Person p1 = new Person("张三",23);
Person p2 = new Person("张三",23);
System.out.println(p1 == p2); 重写前:false 重写后:false
System.out.println(p1.equals(p2)); 重写前:false 重写后:true
}
}
5. clone
protected Object clone(): 创建并返回此对象的副本(浅克隆); 简单理解:复制对象,获取对象的成员
(1)throws CloneNotSupportedException:调用过程中可能存在克隆不支持的异常;对于jdk提供的类
的方法本身存在异常.谁调用这个方法,必须做出处理,否则报错,最简单的方式继续往上抛 throws.
(2)clone为受保护的方法,无关类中不能访问,需要在当前子类中重写clone方法,需要实现Cloneable
接口,这个接口没有字段,连方法都没有,标记接口,标记这个类是否能够使用克隆.
class Persons implements Cloneable{
private String name;
private int age;
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
public class Test {
public static void main(String[] args) throws CloneNotSupportedException {
Persons p1 = new Persons("张三",23);
System.out.println(p1);
Object p2 = p1.clone();
System.out.println(p2);
}
}
6.Scanner
Scanner:java.util的类:文本扫描器
构造方法: public Scanner(InputStream source)
成员方法: <1>判断功能 haxNextXXX():判断下一个录入都是是否是XXX类型
public boolean hasNextInt():
public boolean hasNextLine():
<2>获取功能 nextXXX()
public int nextInt()
public String nextLine() ......
public class ScannerDemo {
public static void main(String[] args) {
//public Scanner(InputStream source):形式参数时候一个抽象类,需要有子类对象
//System类中存在一个"标准输入流"in
//public static final InputStream in
InputStream inputStream = System.in ; //字节输入流
//创建键盘录入对象
Scanner sc = new Scanner(inputStream) ;
System.out.println("录入一个数据:");
/* int num = sc.nextInt(); //获取功能
System.out.println(num);*/
//java.util.InputMismatchException:录入的数据和需要接收的num类型不匹配
//Scanner类的提供的判断功能
if(sc.hasNextInt()){
//录入的int类型
//接收int
int num = sc.nextInt() ;
System.out.println("您输入的数据是:"+num);
}else if(sc.hasNextLine()){
//录入的String
String line = sc.nextLine() ;
System.out.println("您输入的数据是:"+line);
}else{
System.out.println("对不起,没有提供其他接收的类型值...");
}
}
}
十一 . String
抽取方法快捷键: ctrl + alt + m;
1.概念
String类代表字符串,Java程序中的所有字符串文字(例如"abc" )都被实现为此类的实例,"字符串本身就是常量".
2.String的特点
字符串不变的; 它们的值在创建后不能被更改.
推荐访问方式: String 变量名 = "字符串常量" ;
字符串是常量:在内存中:方法区中的常量池中存储
3.面试题
String s = "hello" ;和String s2 = new String("hello") ;两个有什么区别,分别创建了几个对象?
答:共同点:都是在创建一个字符串对象"hello";
不同点:内存执行不一样;前者只是在常量池中开辟空间,创建一个对象;后者在堆中开辟空间,而且常量池里面存在常量----常量池中标记 ,创建两个对象
4.String里的常用构造方法
<1>public String():无参构造
<2>String(byte[] bytes):将字节数组可以构造字符串对象
<3>public String(byte[] bytes,int offset,int length):将一部分字节数组构造成字符串对象
<4>public String(char[] value):将字符数组构造成字符串对象
<5>public String(char[] value, int offset,int count):将一部分字符数组构造成字符串对象
<6>public String(String original):创建一个字符串对象,里面存储字符串常量
5.String类获取功能
<1>char charAt(int index) :获取指定索引处的字符值
<2>public String concat(String str):拼接功能:拼接新的字符串
<3>public int indexOf(int ch):返回指定字符第一次出现的字符串内的索引
<4>public int indexOf(String str):返回指定字符串第一次出现在字符串内的索引
<5>int lastIndexOf(int ch) :查询指定字符最后一次出现的索引值
<6>int length() :获取字符串长度
<7>public String[] split(String regex):字符串的拆分方法:返回字符串数组 (重要)
<8>String substring(int beginIndex) :字符串截取功能(重要),默认从beginIndex开始索引截取到末尾
<9> public String substring(int beginIndex,int endIndex) :从指定位置开始截取到指定位置结束(包前不包后)
6 String类的转换功能
<1>public char[] toCharArray():将字符串转换字符数组
<2>byte[] getBytes() :使用平台的默认字符集进行编码过程:将字符串--->字节数组
<3>byte[] getBytes(String charset):使用指定的字符集进行编码 "GBK/UTF-8"
<4>public String toLowerCase():将字符串中的每一个字符转换成小写
<5>public String toUpperCase():将字符串中的每一个字符转换成大写
<6>static String valueOf(boolean b/float/long/double/int/char /....Object) :万能方法:将任意的数据类型转换成String :静态的功能
7 .String类的判断功能
<1>public boolean contains(String s):判断是否包含子字符串
<2>public boolean startsWith(String prefix):判断是否以指定的字符串开头
<3>public boolean endsWith(String suffix):判断是否以指定的字符串结尾
<4>boolean equals(Object anObject) :判断字符串内容是否相等:区分大小写
<5>boolean equalsIgnoreCase(String anotherString) :判断字符串内容是否相等,忽略大小写
<6>public boolean isEmpty():判断字符串是否为空
8 .String类其他功能
<1>public String replace(char oldChar,char newChar):将新的字符值把旧的字符替换掉
<2>public String replace(String oldChar,String newChar):将新的字符串值把旧的字符串替换掉
<3>public String replaceAll(String regex,String replacement):用指定的replacement替换regex字符串内容
<4>public String trim():去除字符串前后两端空格; 一般用在:IO中传输文件(读写文件)
9 String作为形式参数传递的特点
String类型作为形式参数和基本类型作为形式的效果一样,形式参数的改变不会直接影响实际参
数,String类型为特殊的引用类型.
public class StringTest {
public static void main(String[] args) {
String s1 = "helloworld" ;
System.out.println(s1) ;
change(s1) ;
System.out.println(s1) ;
private static void change(String s1) {//String类型作为形式参数
System.out.println(s1) ;
s1+="javaEE" ;
System.out.println(s1) ;
}
}
十二 .StringBuffer
1.概念
StringBuffer: 简称"字符串缓冲",线程安全的,而且可变的字符序列.
2. StringBuffer面试题
StringBuffer和StringBuilder有什么区别?
答:共同点:两者都是字符串区,支持可变的字符序列,而且都有互相兼容的API(功能相同的);
不同点:<1>前者:线程安全的类,多线程环境下使用居多
<2>后者:线程不安全的类,单线程程序中使用居多
3. StringBuffer的构造方法
<1>StringBuffer();无参构造方法 :使用居多
<2>StringBuffer(int capacity):指定容量大小的字符串缓冲区
<3>StringBuffer(String str) :指定缓冲区的具体内容str,容量大小=16个默认容量+当前字符串长度
<4>public int length()获取字符缓冲区中的长度
<5>public int capacity():获取字符串缓冲区中的容量大小
4. StringBuffer添加和删除功能
<1>StringBuffer append(任何数据类型):将任何数据类型的数据追加字符序列中(字符串缓冲区)
<2>StringBuffer insert(int offset, String str) :插入元素:在指定位置插入指定的元素
<3>public StringBuffer deleteCharAt(int index):在指定的位置处删除的指定的字符,返回字符串缓冲区本身
<4>public StringBuffer delete(int start,int end):删除指定的字符从指定位置开始,到end-1处结束
5. StringBuffer反转功能
public StringBuffer reverse():反转功能.
public String toString():返回表示此数据中的数据的字符串.
6.StringBuffer和String相互转换
(1)Sting转换为StringBuffer
<1>方式1:使用StringBuffer的有参构造方法
String s = "helloJavaEE" ; StringBuffer(String s);
<2>方式2:使用StringBuffer无参构造方法+append(String s)
StringBuffer sb2 = new StringBuffer() ;
sb2.append(s) ;
(2)将StringBuffer转换为String
<1>String类型构造方法:public String(StringBuffer buffer)
String str = new String(buffer) ;
<2>public String toString()
String str2 = buffer.toString();
7.StringBuffer截取功能
substring(int start):从指定位置截取到默认结束,返回的新的字符串.substring(int start, int end) :从指定位置开始截取,到指定位置结束(包前不包后).
StringBuffer sb = new StringBuffer() ;
String resultStr = sb.substring(5);
String resultStr2 = sb.substring(5, 9);
8.String和StringBuffer有什么区别
String:是常量,一旦被赋值,其值不能被更改;它的不可变的字符序列;作为形式参数,形式参数的改变
不会影响实际参数,特殊的引用类型,和基本数据类型作为形式参数的效果一样.
StringBuffer:字符串缓冲区,里面存储的字符序列;是可变的字符序列,线程安全的类,同步,执行效率
低,单线程程序中使用StringBuilder替代StringBuffer;作为形式参数,形式参数的改变会直接影响实际
参数.
十三 . 包装类
1.概念
基本数据类型所对应的引用数据类型;Object可同一所有数据,包装类的默认值是null.
-
byte Byte
-
short Short
-
int Integer
-
long Long
-
float Float
-
double Double
-
char Character
-
boolean Boolean
2. 将Int转换为字符串
<1>public static String toBinaryString(int i):将整数转换字符串形式的二进制
<2>public static String toOctalString(int i) :将整数转换字符串形式的八进制
<3>public static String toHexString(int i):将整数转换成字符串形式的十六进制
System.out.println(Integer.toBinaryString(100)) ;
System.out.println(Integer.toOctalString(100)) ;
System.out.println(Integer.toHexString(100)) ;
3. 求int类型的取值范围
<1>public static final int MAX_VALUE: 求最大值
<2>public static final int MIN_VALUE: 求最小值
-
System.out.println(Integer.MIN_VALUE) ;
-
System.out.println(Integer.MAX_VALUE) ;
-
注意:
jdk5以后:自动拆箱和装箱. 基本数据类型和包装类自动转换.
装箱:基本数据类型---引用数据类型 拆箱:引用数据类型----基本数据类型
4 Integer的构造方法
Integer(int value):将int类型构造成Integer对象
Integer(String s) 将String类型构造成Integer对象: 注意:要使用第二个构造方法,前提是必须是数字
字符串,否则会抛出异常:throws NumberFormatException .
int i = 100 ;
Integer ii = new Integer(i) ;
System.out.println(ii);
String s = "200" ;
Integer i2 = new Integer(s) ;
System.out.println("i2:"+i2) ;
5.基本功能
<1>public static Integer valueOf(int i): int----integer
<2>public static Integer valueOf(String s): String-----Integer
<3>public int intValue(): Integer-----Int 转换为六种基本类型
<4>public String toString(): 返回String表示此对象Integer的价值 Integer------String
<5>public static String toString(int i); int -----String
<6>parseInt(String s): 将字符串解析为带符号的十进制整数 String-----int
6 .典型例题:看程序,写结果
注意:看当前传进来的整数值是否在内存缓冲区-128-127之间;如果在直接取值,如果不在,就会创建
新的Integer对象.
public class IntegerTest {
public static void main(String[] args) {
Integer i1 = new Integer(127) ;
Integer i2 = new Integer(127) ;
System.out.println(i1==i2) ;//false
System.out.println(i1.equals(i2)) ;//true
Integer i3 = new Integer(127) ;
Integer i4 = 127 ;
System.out.println(i3==i4) ;//false
System.out.println(i3.equals(i4)) ;//true
Integer i7 = new Integer(128) ;
Integer i8 = 128 ; //超了范围-128 ~127 new Ineteger(128) ;
System.out.println(i7==i8) ;//false
System.out.println(i7.equals(i8));//true
Integer i5 = new Integer(128) ;
Integer i6 = new Integer(128) ;
System.out.println(i5==i6) ; //false
System.out.println(i5.equals(i6));//true
Integer i9 = 128 ; //-128-127
Integer i10 = 128 ;
System.out.println(i9==i10) ; //false
System.out.println(i9.equals(i10));//true
Integer k1 = 100;
Integer k2 = 100;
System.out.println(k1 == k2);//true
System.out.println(k1.equals(k2));//true
}
}
7.String----与int相互转换
(1)int-----String
<1>方式1:空串拼接
int i = 100 ;
String result = ""+i ;
System.out.println("result:"+result);//"100"
<2>利用Integer中间桥梁
int i = 100 ;
Integer ii = new Integer(i) ;
String result2 = ii.toString();
<3>利用Integer静态方法: public static String toHexString(int i):返回16进制无符号整数值的字符串
int i = 100;
String result3 = Integer.toHexString(i);
(2)String-----int
<1>Integer构造方法+intValue()
String s = "50" ;
Integer i1 = new Integer(s) ;
int intResult = i1.intValue();
<2>Integer静态功能直接转换: public static int parseInt(String s)
String s = "50" ;
int intResult2 = Integer.parseInt(s) ;