面向对象
1.引出
- 首先面向对象就要涉及到类和对象
- 类是抽象的,是对一类事物的描述,用class关键字定义。在一个.java文件中可以有很多的 class,但只有一个能被public修饰,且名字与文件名相同。
- 对象是类的实例化,使用new关键字实现,直接new的是一个匿名对象,每次new都是产 生新对象,也可以使用引用类型的变量指向创建的对象。
2.特征
封装性、继承性、多态和抽象
2.1 java存储
- 一般来讲局部变量存在栈中,方法执行完毕内存就被释放
- 对象(new出来的东西)存在堆中,对象不再被使用时,内存才会被释放
- 每个堆内存的元素都有地址值
- 对象中的属性都是有默认值的
2.2封装性
- 隐藏封装对象的属性和方法,只对外提供公共的访问方式
- 通过private实现,只能在本类访问,提高安全性
- 成员变量被private后,需要提供public的getXxx()获取值/setXxx()设置值
当方法被private后,需要提供间接的访问方式,通过其他public方法调用
2.3继承性
- 继承是从已有的类中派生出新的类,新的类能吸收已有类的数据属性和行为,并能扩展新的能力
- java只支持单继承,继承可以传递
- 不能继承父类的私有成员
- 这种技术使得复用以前的代码非常容易,能够大大缩短开发周期,降低开发费用
- 父类抛出异常,子类可以不抛,要抛的话小于等于父类的异常
2.4多态
- 多态对方法来讲是重载,对对象来讲就是重写
- 父类引用指向子类对象
- 编译看左边,运行看右边(针对方法)
- 多态增强程序的通用性,屏蔽掉了子类之间的不同,把子类当父类来看
- 多态统一了调用标准,只能调用父类
//创建父类,提取子类的共性代码,提高共用性
//创建子类,可以使用父类的功能,减少子类的代码量 - 向上造型就是多态,是为了统一调用标准,提高通用性
向下造型是为了使用子类的扩展功能
3.面向对象的小tips
3.1 构造方法
- 用于对象创建和初始化,新建对象时调用的是无参的构造方法
- 与类同名,修饰词+类名(参数列表){方法体}
- 分为有参无参也就是重载,默认存在无参方法,当出现有参方法时,无参消失
- 子类创建对象时,会默认调用父类的无参构造方法
- 子类构造方法的第一行会默认自动隐藏super()
- 父类没有无参构造,需要手动调用含参构造
3.2 访问控制符
只有public和default可以修饰类
3.3 this和super关键字
- this代表本类对象的一个引用,相当于this帮你创建了一个本类的对象
- this可以调用同一个类里的所有资源(成员变量/方法/构造方法)
- this使用的第一个场景是:用来区别同名的成员变量和局部变量,this调用的一定是成员变量
this使用的第二个场景是:用来在构造方法间互相调用,位置必须是第一条语句+不能形成类似于死循环的样子 - super代表父类的一个引用对象
- 通过super可以调用父类的功能,如果用,必须在调用位置第一行,不和this一起用
3.4 方法的重载和重写
- 同一个类里,方法修饰符和名字相同,参数列表不同的现象就是重载
- override,发生在继承关系里,子类继承父类以后可以使用父类的功能,想要修改方法只能重写,只在子类里生效,OCP原则
- 需要足够的权限(子类权限>=父类的权限),子类的方法声明/签名必须和父类一样
- 抛出的异常小于父类,引用类型的返回值类型小于父类,基本类型返回值要相同
3.5 static关键字
- 可以修饰成员方法,成员变量
- 随着类的加载而加载,优先于对象的加载
- 只加载一次就会一直存在,不用开辟新空间
- 全局唯一,全局共享
- 可以直接被类名调用
- 静态只能调用静态,非静态可以随意调用
- 不能和super、this一起用,有static时可能没有对象
3.6 final关键字
- 被final修饰的类,不能继承
- 被final修饰的方法,不能重写
- 被final修饰的变量,是一个常量,值不能修改
3.7 代码块
- 静态代码块
成员位置,用大括号包起来并且用static修饰,用于项目初始化,随着类的加载而加载 - 构造代码块
成员位置,用大括号包起来,是提取了构造方法的共性,调用构造方法时会首先调用,提高复用性 - 局部代码块
出现在方法里,只有调用方法时才执行
4.异常
- 异常之后的代码不会执行
- Throwable下有个异常子类:error和execption
Error:是不能靠程序能处理的,比如:内存溢出
Exception:运行时异常(非检查异常)和非运行时异常(检查异常) - 常见的运行时异常:控制台出现
1)NullPointerException(空指针异常)当操作一个空引用抛出的一个异常
2)NumberFormatException(数据格式化异常)试图将字符串转换为一种数值类型时,但字符串转换不适当出现的异常。
3)ClassCastException(类型转换异常)强制类型转换不匹配时出现的异常。
4)ArrayIndexOutOfBoundsExveption(数组下标越界异常):当使用一个不存在的下标时出现的异常。
5)ArithmeticException(数字异常):异常运算条件时出现的
非运行时异常:需要抛出的异常
1)SQLException:访问数据库时出现的
2)IOException :当发生某种I/O异常时抛出的
3)ClassNotFoundException:当应用程序使用Class类中的forName方法、loadClass方法时,抛出的异常。 - 在java中可以使用throw来引发异常,使用后必须处理异常
- Finalize是方法名,此方法是在垃圾回收器将对象从内存中清除之前做必要的清理工作
- finally是跟在try catch后的关键字,无论前面是否出现异常里面的代码都会执行,也可以只和try一起使用
5.抽象
- 没有方法体的方法是抽象方法,含有抽象方法的类是抽象类
- 通过Abstract实现,可以修饰类和方法
- 抽象类中可以没有抽象方法,有抽象方法的必须是抽象类
- 子类继承抽象类以后要么是一个抽象类,要么就把所有的抽象方法重写
- 抽象方法不可以实例化
- 抽象类也有构造方法,用于子类的实例化
5.1接口
- 使用interface创建,使用implements让子类实现
- 接口里都是抽象方法,没有构造方法和变量,都是简写的抽象方法和常量,1.8以后有普通方法
- 和继承相似,实现类要么重写所有的抽象方法,要么也是抽象的,而且不能实例化
- 接口间可以多继承,接口可以多实现,还可以继承时多实现
- 接口是对外暴露的规则,是一套开发规范
- 接口提高了程序的功能扩展,降低了耦合性
- 实现类的多态对象左边是谁取决于使用谁的功能
5.2 api
5.2.1 Object
- 是所有类的顶级父类,默认都继承Object类
- toString和equals一般子类要重写
5.2.2 String
- String类是字符串,java程序中所有的字符串字面值都是此类的实例实现
- String a=new String(“12”);调用构造方法,存在堆内存,低效
String b=”23”;简写,存在常量池,高效 - String类被设置成不可被修改,是为了安全性和不可以扩展
- String的工具类StringBuilder(高效)和StringBuffer(安全)是用来拼接字符串,方法为 s.append()还有insert(),delete(),replace(),reverse(),StringBuffer中的方法大都使用了同 步锁synchronized,所以线程比较安全。StringBuilder一般用在单线程时,效率高。
- charAt()获取下标对应值
concat()拼接字符串
endsWith()以…结尾?
startsWith()以…开始?
equals()内容是否相等已重写
hashCode()哈希值码
IndexOf()第一次出现…的下标
lastIndexOf()最后一次出现…的下标
IsEmpty()是否为空
length()长度
replace(1,3)用3取代1
subString()下标开头的子串
subString(1,3)下标1到3的子串
toLowerCase()转换成小写
toUpperCase()转换成小写
trim()去掉两端空格
split()以…分割
matches()是否匹配
valueOf()转换成字符串类型
getBytes()把每个字符转换成码值,存入byte[]
toCharArray()把字符串里的字符存入char[]
5.2.3 Date
- 总结:
Date–用来获取时间的年月日 时分秒 毫秒
SimpleDateFormat–用来把String类型的日期 和 Date 类型的日期 互转
规定日期的模式:yyyy-MM-dd
public class Test2 {
public static void main(String[] args) throws Exception {
// method();//Date
method2();//String->Date SimpleDateFormat
}
//算存活天数
public static void method2() throws Exception {
//1,输入的出生日期
String data = new Scanner(System.in).nextLine();
//2,开始算天数
//2.1,创建对象 -- SimpleDateFormat(String pattern)
SimpleDateFormat sdf =
new SimpleDateFormat("yyyy-MM-dd");
//2.2,Date parse(String text)
Date birthday = sdf.parse(data);//String -> Date
//2.3,算
long start = birthday.getTime();//获取出生时的ms
long now = System.currentTimeMillis();//获取当前时间的ms
System.out.println( (now-start)/1000/60/60/24 );//ms->天
}
5.2.4 BigDecimal和BigInteger
- BigDecimal – 专门解决小数运算不精确的问题
BigInteger – 专门解决超大的整数运算
public class Test3 {
public static void main(String[] args) {
// method();//+-*/
method2();//使用工具
}
public static void method2() {
double a = new Scanner(System.in).nextDouble();
double b = new Scanner(System.in).nextDouble();
//1,创建对象-BigDecimal
// 方式1:BigDecimal(double val) -- 有坑!!!
// BigDecimal bd1 = new BigDecimal(a);
// BigDecimal bd2 = new BigDecimal(b);
// 方式2:BigDecimal(String val) -- 推荐!!!
//需要把参数,从double->String --- String.valueOf()--- +""
BigDecimal bd1 = new BigDecimal(String.valueOf(a));
BigDecimal bd2 = new BigDecimal(b+"");
//2,调用方法
BigDecimal bd3 = bd1.add(bd2);//加法
System.out.println(bd3);
bd3 = bd1.subtract(bd2);//减法
System.out.println(bd3);
bd3 = bd1.multiply(bd2);//乘法
System.out.println(bd3);
//除不尽会抛出异常:java.lang.ArithmeticException
// bd3 = bd1.divide(bd2);//除法
//精确divide(1,2,3)-1是要除谁2是小数位数3是舍入模式
bd3 = bd1.divide(bd2,3,BigDecimal.ROUND_HALF_UP);//除法
System.out.println(bd3);
}
// +-*/
public static void method() {
//接受用户输入的两个小数
double a = new Scanner(System.in).nextDouble();
double b = new Scanner(System.in).nextDouble();
//做运算
System.out.println(a+b);//不精确
System.out.println(a-b);//不精确
System.out.println(a*b);//不精确
System.out.println(a/b);//不精确
}
}
5.2.5 包装类
- 与基本类型一一对应,为基本类型提供丰富的方法
- Number用来把包装类型变成基本类型,它是Float、Double、Byte、Integer、Short、Long的父类
- Integer a=new Integer(5)也叫自动装箱(1.5)编译器认可,虚拟机不认可
Int b=a.intValue()也叫自动拆箱 - 使用Integer a=Integer.valueOf()存数据时,相同数据只存一份,也就是地址相同,但是要在-128~127内,高效
注意
- 将其他类型转换成string的几种方法
1) obj.toString(),obj不能为null,否则抛出空指针异常
2) String.valueOf(obj)
3) (String)obj
4) obj+””,小类型变为大类型加上一个大类型的常量即可