Java基础-04
面向对象
本质:以类的方式组织代码,以对象的组织(封装)数据
- 三大特性
- 封装
- 继承
- 多态
//main方法
public static void main(String[] args) {
Student.say();
// Student.play();
// 报错信息Cannot make a static reference to
// the non-static method play() from the type Student
//非静态方法需要实例化这个类
Student student = new Student();
student.play();
}
public void readFile(String file) throws IOException{
return;
}
//和类一起加在的
public static void a() {
/*
* b(); 报错
* Cannot make a static reference
* to the non-static method b() from the type Demo01
*/
}
//类实例化之后才存在的
public void b() {
}
public class Student {
public static void main(String[] args) {
}
//静态方法 static
public static void say() {
System.out.print("学生说话了");
}
//非静态方法
public void play() {
System.out.print("学生在打游戏");
}
}
public class Demo02 {
public static void main(String[] args) {
//值传递
int a = 1;
System.out.println(a);//1
Demo02.change(a);
System.out.println(a);//1
//引用传递:对象,本质还是值传递
Person person = new Person();
System.out.println(person.name);//null
Demo02.change(person);
System.out.println(person.name);//我叫袁小陌
}
public static void change(int a) {
a = 10;
}
public static void change(Person person) {
//person是一个对象
person.name = "我叫袁小陌";
}
}
class Person{
String name;
}
构造器
构造器也称构造方法,是在进行创建对象的时候必须要调用的
- 特点
- 必须和类的名字相同
- 必须没有返回类型,也不能写void
//属性 字段
String name;
//使用new 本质上是调用构造器
//用来初始化值
public Person() {
this.name = "我叫袁小陌";
}
//有参构造:一旦定义了有参构造,无参必须显示定义
public Person(String name) {
this.name = name;
}
//IDEA的快捷键 alt+insert
public class Application {
public static void main(String[] args) {
//类是抽象的 ,需要实例化
//类实例化后会返回一个自己的对象
// Student xiaoming = new Student();
// Student xiaohong = new Student();
// System.out.println(xiaoming.name);//null
//
// xiaoming.name = "小明";
// System.out.println(xiaoming.name);//小明
Person person = new Person();
System.out.println(person.name);//我叫袁小陌
Person person1 = new Person("张三");
System.out.println(person1.name);//张三
}
}
封装
private 属性私有(IDEA的alt+insert可以快速插入get/set方法)
//属性私有 private
//名字
private String name;
//学号
private int id;
//性别
private String sex;
//年龄
private int age;
//提供一些可以操作这些属性的方法,提供一些public的get、set方法
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return this.age;
}
public void setAge(int age) {
if (age>=120 || age<0) {
this.age = 3;
}else {
this.age = age;
}
}
继承
关键字 extends / super
- super注意点
- super调用父类的构造方法,必须是构造方法的第一个
- super必须只能出现在子类的方法或者构造方法中
- super和this不能同时调用构造方法
Vs this
- 代表的对象不同:
- this 本身调用者的这个对象
- super 代表父类对象的应用
- 前提:
- this 没有继承也可使用
- super 只能在继承下面使用
- 前提:
- this(); 本类的构造
- super(); 父类的构造
//java中所有的类都默认继承object类
public class Person {
//public
//protected
//default
//private 私有的公司无法被继承
protected String name = "小陌-父类";
public Person() {
System.out.println("Person无参构造器执行");
}
public int money = 10_000_000;
//Eclipse 快捷键 alt + shift +s
// Eclipse 查看继承树 ctrl+T IDEA:ctrl+H
public int getMoney() {
return money;
}
public void setMoney(int money) {
this.money = money;
}
public void Say() {
System.out.println("老师说了一句话");
}
}
public class Student extends Person {
public Student() {
super();//会默认调用
System.out.println("Student无参构造器执行");
}
protected String name = "小陌-学生";
public void test(String name) {
System.out.println(name);
System.out.println(this.name);
System.out.println(super.name);
}
}
public class Application {
public static void main(String[] args) {
Student stu = new Student();
// Person无参构造器执行
// Student无参构造器执行
// stu.Say();
// stu.test("胡歌");
}
}
重写
需要有继承关系:子类重写父类的方法
- 方法名必须相同
- 参数列表必须相同
- 修饰符:范围可以扩大 public > protected > default > private
- 抛出的异常:范围可以被缩小,但是不能被放大ClassNotFoundException --> Exception(大)
- 子类和方法和父类必须要一致,方法体不同
//静态方法和非静态方法区别很大
//静态方法 //方法的调用只和左边,定义的数据类型有关
//非静态方法 重写
public static void main(String[] args) {
A a = new A();
a.test();//A>>test()
//父类的引用指向了子类
B b = new A();// 子类重写了父类的方法
b.test();//B>>test() 重写后变成 A>>test()
}
public class A extends B{
// public static void test(){
// System.out.println("A>>test()");
// }
// public void test(){
// System.out.println("A>>test()");
// }
@Override //注解:有功能的注释
public void test() {
// super.test();
System.out.println("A>>test()");
}
}
public class B {
// public static void test(){
// System.out.println("B>>test()");
// }
public void test(){
System.out.println("B>>test()");
}
}
多态
- 多态是方法的多态
- 父类和子类,有联系 类型转化异常ClassCastException
- 存在条件 继承关系,方法需要重写,父类的引用指向子类对象Father f1 = new Son();
- static 方法 属于类 他不属于实例
- final 常量
- private方法私有无法重写
public class Person {
public void run(){
System.out.println("run");
}
}
public class Student extends Person{
@Override
public void run() {
System.out.println("son");
}
public void eat(){
System.out.println("eat");
}
}
//一个对象的实际类型是确定的
//new Person();
//可以指向的引用类型就不确定了
//Student类型能调用的方法都是自己的或者继承父类的
Student s1 = new Student();
//Person父类型 可以指向子类,但是不能调用子类独有的方法
//类型之间的转换 父 子
//高 低
Person s2 = new Student();
Object s3 = new Student();
Person s4 = new Person();
//对象能执行哪些方法,主要看左边有哪些类型和右边关系不搭
s1.run();//son
s1.eat();//eat
s2.run();//son
s4.run();//run
// s2.eat();//报错 Cannot resolve method 'eat' in 'Person'
//s2 将这个对象转换为Student类型 我们就可以使用Student类型的方法
((Student)s2).eat();//强制转换 eat
类型转换
- 父类的引用转向子类的对象
- 把子类转换为父类,向上转型
- 把父类转换为子类,向下转型:强制转换
- 方便方法的调用,减少重复的代码
static关键字
package oop.Demo07;
//静态导入包
import static java.lang.Math.random;
public class Student {
private static int age;//静态变量
private double score;//非静态变量
{
//代码块 匿名代码块 常用来赋初始值
System.out.println("anonymous Code");
}
static {
//静态代码块 类加载直接执行 永久只加载一次
System.out.println("Static Code");
}
public Student(){
System.out.println("constructor Code");
}
public static void main(String[] args) {
Student s1 = new Student();
// System.out.println(Student.age);
// System.out.println(s1.score);
// System.out.println(s1.age);
}
}
/*
执行顺序
Static Code 静态代码块
anonymous Code 匿名代码块
constructor Code 构造方法
*/
抽象类
//abstract 抽象类
public abstract class Action {
//约束别人帮我们实现
//abstract 抽象方法 只有方法名字 没有方法的实现
public abstract void doSomething();
//抽象类不能被new 只能靠子类去实现他
//抽象类中可以写普通方法
//抽象方法必须在抽象类中
public static void main(String[] args) {
// new Action();// 'Action' is abstract; cannot be instantiated
}
}
//抽象类的所有方法 继承了它的子类 都必须要实现他的方法
public class A extends Action{
@Override
public void doSomething() {
}
}
接口
- 作用
- 约束
- 定义一些方法,让不同的人实现
- 方法都是public abstract
- 常量都是public static final
- 接口不能实例化 没有构造方法
- implements是可以实现多个接口
- 必须重写接口中的方法
public interface UserService {
//常量 public static final
int age = 99;
//接口中的所有定义其实都是抽象的 public abstract
void add(String name);
void delete(String name);
void update(String name);
void query(String name);
}
public interface TimerService {
void timer();
}
//类可以实现接口 implements 接口
//实现了接口的类 必须要重写接口中的方法
public class UserServiceImpl implements UserService,TimerService {
@Override
public void add(String name) {}
@Override
public void delete(String name) {}
@Override
public void update(String name) {}
@Override
public void query(String name) {}
@Override
public void timer() {}
}
内部类
public class Outer {
private int id=10;
public void out(){
System.out.println("out");
//局部内部类
class Inner2{
}
}
public class Inner{
public void in(){
System.out.println("in");
}
public void getId(){
System.out.println(id);
}
}
public static void main(String[] args) {
//没有初始化类 不用将实例保存到变量中
new A().eat();
UserService userService = new UserService(){
@Override
public void hello() {
}
};
}
}
//一个java类中可以有多个class类,但是只能有一个public class
class A{
public void eat(){
System.out.println("1");
}
}
interface UserService{
void hello();
}
public class Application {
public static void main(String[] args) {
Outer outer = new Outer();
//通过外部内实例化内部类
Outer.Inner inner = outer.new Inner();
inner.in();
inner.getId();
}
}
异常
- RuntimeException
- ArrayIndexOutOfBoundsException
- NullPointerException
- ArithmeticException
- MissingResourceException
- ClassNotFoundException
处理机制
关键字 try catch finally throw throws
public static void main(String[] args) {
int a = 1;
int b = 0;
//.ArithmeticException: / by zero
// System.out.println(a/b);
try {
new Demo01().test(a,b);
} catch (ArithmeticException e) {
e.printStackTrace();
}
//如果要捕获多个异常:要从小到大
//快捷键 Ctrl+Alt+T
try {
System.out.println(a/b);
}catch (ArithmeticException e){ //想要捕获的异常类型;
System.out.println("除数不能为0");
e.printStackTrace();//打印错误的栈信息
}finally{
System.out.println("finally");
}
}
//假设在这个方法中处理不了这个异常,方法上抛出这个异常
public void test(int a,int b) throws ArithmeticException{
if (b==0){
throw new ArithmeticException();//主动抛出异常 一般在方法中使用
}
}
自定义异常
- 创建自定义异常类(继承Exception)
- 在方法中通过throw关键字抛出异常对象
- 如果在当前抛出异常的方法中处理异常,可以使用try-catch语句捕获并处理;否则在方法中声明处通过throws关键字指明要抛出给方法调用者的异常,继续执行下一步操作
- 在出现异常方法的调用者中捕获并处理异常
//自定义异常类
public class Demo02 extends Exception{
//传递数字>10
private int detail;
public Demo02(int a){
this.detail = a;
}
//异常的打印信息
@Override
public String toString() {
return "Demo02{" +
"detail=" + detail +
'}';
}
}
static void test1(int a) throws Demo02 {
System.out.println("传递的参数为"+a);
if (a>10){
throw new Demo02(a);
}
}
public static void main(String[] args) {
try {
test1(11);
} catch (Demo02 e) {
System.out.println("MyException>>"+e);
}
}
总结
- 处理运行时异常的时候,采用逻辑去合理规避同时辅助try-catch处理
- 在多重catch块后面,可以加上一个catch(Exception)来处理可能会遗漏的异常
- 对不确定的代码,切忌只是简单的调用printStackTrace()去打印
- 具体如何处理异常,要根据不同的业务需求和异常类型去决定
- 尽量添加finally语句块去释放占用的资源

浙公网安备 33010602011771号