封装
java三大特性:封装、继承、多态。封装是面向对象的三大特征之一,适当的封装可以让代码更容易理解与维护,也加强了代码的安全性
private关键字
- private关键字是一个权限修饰符,代表最小权限
- 可以修饰成员变量和成员方法
- 被private修饰后的成员变量和成员方法,只能在本类中进行访问
- 提供set和get方法进行赋值和取值
权限修饰符范围
序号 | 范围 | private | default | protected | public |
---|---|---|---|---|---|
1 | 同一包中的同一类 | 可以 | 可以 | 可以 | 可以 |
2 | 同一包中的不同类 | 可以 | 可以 | 可以 | |
3 | 不同包中的子类 | 可以 | 可以 | ||
4 | 不同包中的非子类 | 可以 |
this关键字
this关键字代表所在类的当前对象的引用(地址值),即对象自己的引用
方法被哪个对象调用,方法中的this就代表那个对象。即谁在调用,this就代表谁
类对象作为方法中的参数传递
测试
class Person {
public void say(Student student) {
student.say();
}
}
class Student {
public void say() {
System.out.println("您好!!");
}
}
public class Demo09 {
public static void main(String[] args) {
//创建一个Student对象
Student student = new Student();
//创建一个Person对象
Person person = new Person();
//调用say方法,传参student对象
person.say(student);
}
}
继承
继承是面向对象三大特征之一,继承就是子类继承父类的特征(属性)和行为,使得子类对象(实例)具有父类的属性和方法,或子类从父类继承方法,使得子类具有父类相同的行为。
继承可以使得子类别具有父类别的各种属性和方法,而不需要再次编写相同的代码。在令子类别继承父类别的同时,可以重新定义某些属性,并重写
某些方法,即覆盖父类别的原有属性和方法,使其获得与父类别不同的功能。另外,为子类别追加新的属性和方法也是常见的做法。
语法格式
class 父类 {
...
}
class 子类 extends 父类 {
...
}
总结
- 至少两个类,使用extends关键字
- 子类只能继承父类非私有化的成员变量和成员方法
- 子类可以重写某些父类的方法
- 子类可以额外添加子类独有的方法
继承的内存分析
方法重写和方法重载
方法重写
重写目的:子类可以继承父类的非私有化的方法,但是有的 时候父类的需求满足不了子类的需求了,这个时候需要重写父类非私有的方法。
总结
- 必须要有继承关系
- 父类中的成员方法不能是私有化的
- 在子类中重写父类方法
- 除了方法体不同,其他都一样
方法重载
- 方法重载是在一个类中
- 方法名一样,参数列表或返回值等不同
- 无参构造方法和有参构造方法也是一种重载
super关键字
super
关键字:用于修饰父类成员变量,类似于之前学过的this
;this
代表的是本类对象,而super
代表的是父类对象;使用super
我们可以调用父类的成员(属性和行为),注意super关键字不能访问父类私有(private修饰)的成员
作用
- 用于访问父类中的成员变量
- 调用父类中的成员方法
- 在子类构造方法中调用父类的构造方法
抽象abstract关键字
定义
-
抽象类:关键字abstract修饰的类,含有抽象方法
abstract class 类名 { }
-
抽象方法:关键字abstract修饰的方法,这种方法没有方法体
修饰符 abstract 返回值类型 方法名 (参数列表);
总结
1.如果一个类中用abstract修饰的话,那么这个类叫抽象类
2.抽象类中可以有普通成员方法和抽象方法
3.抽象方法没有方法体,是不完整的方法
4.抽象类不能被实例化
5.写一个普通的类去继承抽象类
6.在子类中一定去实现(重写)抽象类中所有的抽象方法
7.非抽象方法可以重写也可以不重写
8.一个抽象类能不能去继承另外一个抽象类? 可以的!!!
9.抽象类可以继承非抽象类
final关键字
fianl可以修饰类、方法、变量等
final修饰成员变量:修饰时要赋值,一旦赋值后无法改变
final修饰局部变量:使用该局部变量前要赋值,一旦赋值后无法改变
final修饰方法:该方法不能被子类重写
final修饰类:该类不能被继承
final修饰类对象的引用:修饰后不能被其他同类对象赋值
接口
接口概述
接口(英文:Interface),在Java编程语言中是一个抽象类型,接口中定义的全都是抽象方法,使用Interface来声明。一个类通过继承接口的方式,从而来继承接口的抽象方法。
一个类继承接口则需要实现该接口的所有的抽象方法,除非继承接口的类是抽象类,因此一个类继承接口我们往往称为某个类实现了(implements)某个接口,关键字从extends更换为implements。
tips:在JDK7及以前,接口中只含有抽象方法;在JDK8中,接口可以含有默认方法以及静态方法;JDK9中,接口可以含有私有方法;
总结
-
使用关键字interface声明接口
-
接口下面可以有属性,但是是被static和final修饰
interface A { String name = "李四"; }
-
接口下面可以有方法,但是是抽象的方法,也就是说没有方法体
interface A { public void shot(); }
-
jdk1.8以后是可以有默认(default)的方法的,这个默认方法带有方法体【重点!!!】
interface A { default public void say() { System.out.println("jdk8新特性,默认方法有方法体"); } }
-
接口中没有构造方法,不能被实例化
-
普通类使用关键字implements实现接口
-
普通类中要实现接口中的方法
-
普通类可以实现多个接口,弥补了单继承的局限性
-
接口可以继承另一个接口
interface A { default public void say() { System.out.println("jdk8新特性,默认方法有方法体"); } void shot (); } interface B extends A{ } class C implements B { @Override public void shot() { // TODO Auto-generated method stub System.out.println("嘿嘿嘿嘿嘿嘿"); } } public class Demo01 { public static void main(String[] args) { C c = new C(); c.shot(); } }
多态
满足条件
- 要有继承关系
- 重写父类方法
- 父类的引用指向子类的对象
- 编译看
=
左边,运行看=
右边
向上转型
父类的引用指向子类的对象
向下转型(强转)
-
先向上转型:父类的引用指向子类的对象
-
在向下转型:子类的引用指向父类的引用
//向下转型,先向上转型,再向下转型 Pizza pizza1 = new Bacon(); Bacon bacon = (Bacon) pizza1;
instanceof 关键字
返回值类型是布尔值类型。测试左边的对象是否是右边类或者该类的子类创建的实例对象
语法格式
对象 instanceof 类名
//左边辈分低,右边辈分高,或者二者平辈,返回true,否则返回false
示例
class Peoson1 {
public void say(Peoson1 peoson1) {
System.out.println(peoson1);
}
// public void say(Student student) {
// System.out.println(student);
// }
// public void say(Student1 student1) {
// System.out.println(student1);
// }
}
class Student extends Peoson1 {
public void shot () {
}
}
class Student1 extends Peoson1 {
}
public class Demo02 {
public static void main(String[] args) {
Peoson1 peoson1 = new Student();
//instanceof关键字用法
System.out.println(peoson1 instanceof Student);//结果为true
}
}
static关键字
修饰成员变量,称为静态属性
class A {
static String name;//静态属性,与对象无关。name与age相比会变为斜体
int age;
}
public class Demo01 {
public static void main(String[] args) {
A a = new A();
a.age = 12;
//对象无法.name 赋值
//通过类名.name 赋值
A.name = "卡哇伊";
}
}
修饰成员方法,称为静态方法
class A {
//静态方法
static public void say () {
System.out.println("哈哈哈哈哈");
}
}
public class Demo01 {
public static void main(String[] args) {
A a = new A();
//无法通过对象调用静态方法
//通过类调用静态方法
A.say();
}
}
修饰代码块,静态代码块
class A {
static {
System.out.println("咿呀咿呀咿呀");
}
//静态方法
static public void say () {
System.out.println("哈哈哈哈哈");
}
}
public class Demo01 {
public static void main(String[] args) {
A.say();
}
}
加载A这个类时,静态代码块会先执行
咿呀咿呀咿呀
哈哈哈哈哈
内存分析
异常
异常概述:程序运行过程中出现的问题在Java中被称为异常,异常本身也是一个Java类,封装着异常信息;我们可以通过异常信息来快速定位问题所在;我们也可以针对性的定制异常,如用户找不到异常、密码错误异常、页面找不到异常、支付失败异常、文件找不到异常等等…
默认情况下,出现异常时JVM默认的处理方式是中断程序执行,因此我们需要控制异常,当出现异常后进行相应修改,提供其他方案等操作,不要让程序中断执行;
常见异常:
- 空指针异常
java.lang.NullPointerException
- 数组下标越界异常
java.lang.ArrayIndexOutOfBoundsException
- 类型转换异常
java.lang.ClassCastException
- 算数异常
java.lang.ArithmeticException
异常事件
- Error:表示严重错误,一般是JVM系统内部错误、资源耗尽等严重情况,无法通过代码来处理;
- Exception:表示异常,一般是由于编程不当导致的问题,可以通过Java代码来处理,使得程序依旧正常运行;
异常分类
- 编译时异常
- 运行时异常
异常处理
捕获异常(try ----catch)
语法格式
try {
// 可能会出现异常的代码
} catch (Exception1 e) {
// 处理异常1
} catch (Exception2 e) {
// 处理异常2
} catch (ExceptionN e) {
// 处理异常N
}
try {
// 可能会出现异常的代码
} catch (Exception1 e) {
// 处理异常1
} catch (Exception2 e) {
// 处理异常2
} catch (ExceptionN e) {
// 处理异常N
} finally {
// 不管是否出现异常都会执行的代码
}
try…catch语句是可以单独使用的;即:不要finally代码块
抛出异常
Java提供了一个throw关键字,它用来抛出一个指定的异常对象;抛给上一级;
自己抛出的异常和JVM抛出的异常是一样的效果,都要进行处理,如果是自身抛出的异常一直未处理,最终抛给JVM时程序一样会终止执行
语法格式
throw new 异常类名(参数);
示例
public class Demo02 {
public static void main(String[] args) {
int[] arr = new int[2];
arr[0] = 1;
arr[1] = 2;
try {
method(arr, 4);
} catch (ArrayIndexOutOfBoundsException e) {
// e.printStackTrace();
System.out.println(e.getMessage());
}
}
public static void method(int[] arr, int a) {
if (a > 2) {
// 手动抛出异常(抛出异常后,后面的代码将不会被执行)
//调用者依旧要处理异常
throw new ArrayIndexOutOfBoundsException("下标越界了!!!");
}
//这句话不会执行
System.out.println(arr[3]);
}
}
throws关键字
语法格式
... 方法名(参数) throws 异常类名1,异常类名2…{ }
示例
public class Demo02 {
public static void main(String[] args) {
int[] arr = new int[2];
arr[0] = 1;
arr[1] = 2;
// 如果调用的方法上声明了编译时异常,那么在调用方法时
// 就一定要处理这个异常,可以选择继续网上抛,也可以选择try..catch处理
try {
method(arr, 5);
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println(e.getMessage());
}
}
// 如果方法声明了编译时异常,那么在调用方法时就一定要处理这个异常
public static void method(int[] arr, int a) throws ArrayIndexOutOfBoundsException{
if (a > 2) {
// 手动抛出异常(抛出异常后,后面的代码将不会被执行)
//调用者依旧要处理异常
throw new ArrayIndexOutOfBoundsException("下标越界了!!!");
}
//这句话不会执行
System.out.println(arr[3]);
}
}
异常的常用方法
-
public void printStackTrace()
:获取异常的追踪信息;包含了异常的类型,异常的原因,还包括异常出现的位置,在开发和调试阶段,都得使用printStackTrace。
-
public String getMessage()
:异常的错误信息;
String类–API的使用
声明方式
public class Demo03 {
public static void main(String[] args) {
//第一种
String name = "卡哇伊";
String name1 = "卡哇伊";
//第二种
String s = new String("卡哇伊");
System.out.println(name == name1);//true
System.out.println(s == name);//false
}
}
内存分析
常用方法