Java面向对象

一、基本定义

1. 面向对象的特点

  • 将复杂的事情简单化
  • 面向对象这种思想是符合现在人们思考习惯的一种思想
  • 过程其实就是函数;对象是将函数等一些内容进行了封装

2. 类和对象

类:对事物、逻辑、算法或概念的抽”描述一类对象的行为(函数)和状态(变量)
对象:对象是类的一一个实例有状态和行为

3. 构造函数

用于给对象进行初始化,分析事物时,发现具体事物一出现,就具备了一些特征,那就将这些特征定义到构造函数内。

//语法:函数的名称和所在类的名称相同,不需要定义返回值类型。
//无惨构造
public 类名(){
}
//有参构造
public 类名(String name){
    this.name=name;
}

4. static

各个对象的共有属性,静态随着类的加载而加载。想要实现对象中的共性数据,可以将这个数据进行静态修饰。因为静态方法加载时,优先于对象存在,所以没有办法访问对象中的成员,静态方法只能访问静态成员,不可以访问非静态成员,不能使用this、super关键字。
static的作用域

  • 静态方法中可以直接调用同类中的静态成员,但不能直接调用非静态成员
  • 在静态方法中调用非静态变量,通过创建类的对象,然后通过对象来访问非静态变量
  • 静态方法中不能直接调用非静态方法,需要通过对象来访问非静态方法

静态初始化块

  • 静态初始化块只在类加载时执行,且只会执行一次
  • 静态初始化块只能给静态变量赋值,不能初始化普通的成员变量
static{}

5. final

  • 被final修饰的类是一个最终类,不可以被继承
  • 被final修饰的方法是一个最终方法,不可以被覆盖
  • 被final修饰的变量是一个常量,只能赋值一次,常量应该用大写命名

二、封装

隐藏对象的属性和实现细节,仅对外提供公共访问方式。将变化隔离;便于使用;提高重用性;安全性。

//注意:私有仅仅是封装的一种体现形式而已
private int age;
//可以在函数中加入逻辑判断等操作,对数据进行判断等操作。
public void setAge(int age){
    this.age=age;
}
public int getAge(){
    return this.age;
}

三、继承

继承是子类自动共享父类数据和方法的机制,提高了软件的可重用性和可扩展性。
子类覆盖父类时,必须要保证,子类方法的权限必须大于等于父类方法权限可以实现继承。
静态只能覆盖静态,或者被静态覆盖。被final修饰的方法或者属性不能被继承。

1. java对象的初始化顺序

本类的初始化顺序
静态变量、静态初始化块、变量、初始化块、构造函数
继承类的初始化顺序
父类静态变量、父类静态初始化块、子类静态变量、子类静态初始块、父类变量、父类初始化块、父类构造函数、子类变量、子类初始化块、子类构造函数

2. 继承关系中的成员

成员变量
当子父类中出现一样的属性时,子类类型的对象,调用该属性,值是子类的属性值,如果想要调用父类中的属性值,需要使用一个关键字:super。

  • This:代表是本类类型的对象引用。
  • Super :代表是子类所属的父类中的内存空间引用。

成员函数

  • 重写Override:子类中的方法与父类中的某个方法的名称和参数完全相同
    • 子类覆盖父类的方法时,只能出抛出父类的相同或子异常
    • 子类方法的访问权限只能比父类的更大
  • 重载Overload:同一个类中有多个名称相同的方法,但这些方法的参数列表各不相同,与方法是什么类型返回值无关。
    • 在使用重载时只能通过不同的参数类型,不同的参数个数,不同的参数顺序
    • 不能通过访问权限、返回类型、抛出的异常进行重载
    • 方法的异常类型和数目不会对重载造成影响

构造函数
子类的所有构造函数中的第一行,其实都有一条隐身的语句super()
super(): 表示父类的构造函数,并会调用于参数相对应的父类中的构造函数。

四、多态

多态是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,因为在程序运行时才确定具体的类,不用修改源程序代码,就可以让引用变量绑定到各种不同的类实现上,让程序可以选择多个运行状态,这就是多态性。多态性增强了软件的灵活性和扩展性。

1. 多态的体现

父类引用作为形参,子类对象作为实参传入。
多态的前提是发生了继承和重写,实现要看子类,编译看左边,运行看右边(左边是声明的父类引用,右边是new出来的子类对象)

2. 多态的转型

向上转型
多态本身就是向上转型过的过程
使用格式:父类类型 变量名=new 子类类型();
适用场景:父类引用作为形参,子类对象作为实参传入
向下转型
一个已经向上转型的子类对象可以使用强制类型转换的格式,将父类引用类型转为子类引用各类型
使用格式:子类类型 变量名=(子类类型) 父类类型的变量;
适用场景:当要使用子类特有功能时

五、抽象类

对一类事物在不断抽取过程中,将共性内容中的方法声明抽取,其中完全相同的行为抽象为具体的方法实现,而各类各有特点的行为抽取到的方法并不具体,这些方法需要被指定关键字abstract所标示,声明为抽象方法。抽象方法所在类一定要标示为抽象类,也就是说该类需要被abstract关键字所修饰。

1. 抽象类的特点

  • abstract可以描述类和方法,不可以描述变量
  • abstract不可以和final、private、static共存
  • 抽象类有构造方法,接口中没有构造方法
  • 抽象方法只定义方法声明,并不定义方法实现
  • 抽象类不可以被创建对象
  • 子类继承抽象类并覆盖了抽象类中的所有抽象方法后,该子类才可以实例化,否则,该子类还是一个抽象类

2. 抽象类的实现

 abstract class A{//定义一个抽象类

public void fun(){//普通方法
System.out.println("存在方法体的方法");
}

public abstract void print();//抽象方法,没有方法体,有abstract关键字做修饰

}

六、接口

接口是两个模块之间通信的标准,通信的规范。定义好模块之间的接口,就相当于完成了系统的设计大纲,剩下的就是添砖加瓦的具体实现了。工作以后做系统时往往就是使用“面向接口”的思想来设计系统。接口和实现类不是父子关系,是实现规则的关系。Java可以通过实现接口来实现多继承,也被用来实现解耦。

  • 从接口的实现者角度看,接口定义了可以向外部提供的服务。
  • 从接口的调用者角度看,接口定义了实现者能提供那些服务。

1. 接口的特点

  • 接口指明了一个类必须要做什么和不能做什么
  • 接口中定义的变量只能是public static final类型,抽象方法只能是public类型的
  • 一个类可以实现多个接口,但只能继承一个抽象类
  • 抽象方法只能存在于抽象类或者接口中,但抽象类中却能存在非抽象方法,即有方法体的方法。接口是百分之百的抽象类

2. 接口的实现

//声明接口
interface aaa{
    //属性被public static final修饰默认不写
    int a = 10;
    //方法被public abstract修饰默认不写
    void display();
}
//实现接口
//用implements
public class a() implements aaa{
    public void display(){            
    }
}

七、异常

异常是指java程序运行时所发生的错误,Java使用面向对象的方式来处理异常,把程序中发生的异常封装到成对象来表示,该对象中包含有异常的信息。

  • Throwable
    • Error:应用程序本身无法克服和恢复的一种严重问题(内存溢出和线程死锁等系统问题)

    • Exception:软件开发人员考虑不周所导致的问题,程序还能够克服和恢复

      • 系统异常:软件本身缺陷所导致的问题,编译时,不会提示和发现这样的异常,可以处理可以不处理。对于这些异常我们应该修正代码,而不是通过异常处理器处理。原因多半是由于我们的代码逻辑出现了问题。(ArithmeticException、ClassCastException)
      • 普通异常:运行环境的变化或异常所导致的问题,要么用try-catch语句捕获它并处理,要么用throws子句声明抛出它,否则编译不会通过(SQLException,IOException,ClassNotFoundException)

1. 处理过程

抛出异常:在执行一个方法时。如果发生异常则这个方法生成代表该异常的一个对象,停止当前执行路径,并把异常对象提交给JRE。
捕获异常:JRE得到该异常后,寻找相应的代码来处理该异常。JRE在方法的调用栈中查找,从生成异常的方法开始回溯直到找到相应的异常处理代码为止。

2. 处理异常

//在同一try…catch…finally…块中,如果try中抛出异常,如果没有catch块匹配,则先执行finally,然后去到上层的调用者中寻找合适的catch块
//在同一try…catch…finally…块中,try发生异常,且匹配的catch块中处理异常时也抛出异常,那么后面的finally也会执行:首先执行finally块,然后去上层调用者中寻找合适的catch块
//如果在try中添加return,要先执行finally在执行return,如果同时finally中也有return则会忽略try中的return
try{
    //可能发生异常的代码
}catch(Exception e){
    //括号定义了异常类型和异常参数
    //可以使用这个块的异常参数来获取异常的相关信息
    //可以定义多个catch,虚拟机使用最先匹配到的catch块来处理异常,所以要把子异常写在前面
    //所有catch都没捕获到,先去执行finally,然后到这个方法的外部调用者中去匹配异常处理器
}finally{
    //finally块不是必须的,是可选的
    //无论是否发生异常都会执行finally代码块
    //finally主要做一些清理工作,如流的关闭,数据库连接的关闭等
    //在try块中打开资源,在finally块中清理并释放这些资源,以免造成内存泄露
}

//throws关键字仅仅是将方法中可能出现的异常向调用者抛出,而自己则不具体处理
//采取这种异常处理的原因可能是:方法本身不知道如何处理这样的异常,或者说让调用者处理更好,调用者需要为可能发生的异常负责
public static int divide(int x,int y) throws Exception{
    int result = x/y;
    return result;
}
//throw语句手动显式的抛出一个异常,throw语句的后面必须是一个异常对象
public void save(User user) {
    if (user == null)
        // //将参数信息添加到异常信息中
        throw new IllegalArgumentException("User对象为空");
}

3. 自定义异常

//选择继承 Throwable,Exception 或它们的子类
public class MyException extends RuntimeException{ } 
public class MyException extends Exception{
    static final long serialVersionUID = 7818375828146090155L;
    //无参构造函数
    public IOException() {
        super();
    }
    //带有String参数的构造函数,并传递给父类的构造函数
    public IOException(String message) {
        super(message);
    }
    //带有String参数和Throwable参数,并都传递给父类构造函数
    public IOException(String message, Throwable cause) {
        super(message, cause);
    }
    //带有Throwable 参数的构造函数,并传递给父类的构造函数
    public IOException(Throwable cause) {
        super(cause);
    }
}

八、枚举类

枚举类就是对象个数有限且确定的类,使用enum定义的枚举类,里面的内容是实例,需要定义一组常量时使用枚举类。
枚举类相比于常量更加直观,类型安全。若一个方法中要求传入季节这个参数,用常量的话,形参就是int类型,开发者传入任意类型的int类型值就行,但是如果是枚举类型的话,就只能传入枚举类中包含的对象。

1. 枚举类的特点

  • 多个枚举变量直接用逗号隔开,默认被public static final修饰
  • 默认继承了Enum,而不是继承Object类
  • 默认使用final修饰不可以被继承
  • 枚举类的构造器只能是私有的
  • switch语句里的表达式可以是枚举值

2. 枚举类的使用

//简单的枚举类
public enum Season {
    SPRING,SUMMER,AUTUMN,WINTER
}

//枚举类内也可以定义属性和方法,可是是静态的和非静态的
public enum Week {

    // 枚举对象
    MONDAY("星期一","上一天的语文课"),
    TUESDAY("星期二","上一天的数学课"),
    WEDNESDAY("星期三","上一天的英语课"),
    THURSDAY("星期四","上一天的物理课"),
    FRIDAY("星期五","上一天的化学课"),
    SATURDAY("星期六","上一天的生物课"),
    SUNDAY("星期日","上一天的自习课");

    //声明属性
    private final String weekName;
    private final String weekDesc;
    //构造方法
    Week(String weekName, String weekDesc) {
        this.weekName = weekName;
        this.weekDesc = weekDesc;
    }

    // 其他方法:getter方法,toString()方法等
    public String getWeekName() {
        return weekName;
    }

    public String getWeekDesc() {
        return weekDesc;
    }
    //重写父类toString

    @Override
    public String toString() {
        return "Week{" +
                "weekName='" + weekName + '\'' +
                ", weekDesc='" + weekDesc + '\'' +
                '}';
    }
}
//测试

System.out.println(Week.SUNDAY); //Week{weekName='星期日', weekDesc='上一天的自习课'}
System.out.println(Week.SUNDAY.getWeekName()); //星期日
System.out.println(Week.SUNDAY.getWeekDesc()); //上一天的自习课

3. 枚举类实现接口

//枚举类可以实现一个或多个接口
// 定义一个接口
interface AA{
    void sayHello();
}
//全局实现:就在枚举类中直接实现,此时所有的枚举对象都拥有相同的方法实现
public enum SeasonWithInterface implements AA {
    Spring,SUMMER,AUTUMN,WINTER;


    @Override
    public void sayHello() {
        System.out.println("Hello EveryOne!");
    }
}
//对象实现:声明对象的时候实现,此时每个对象都单独对接口中的方法进行实现
public enum SeasonWithInterface implements AA {
    SPRING(){
        @Override
        public void sayHello() {
            System.out.println("Hello Spring");
        }
    },
    SUMMER(){
        @Override
        public void sayHello() {
            System.out.println("Hello SUMMER");
        }
    },
    AUTUMN(){
        @Override
        public void sayHello() {
            System.out.println("Hello AUTUMN");
        }
    },
    WINTER(){
        @Override
        public void sayHello() {
            System.out.println("Hello WINTER"); 
        }
    };


}

4. 枚举类的常用方法

  • values():返回枚举类中的枚举对象的数组,可以方便进行遍历
  • valueOf(String objName):返回枚举类中与参数objName名称一致的枚举对象,参数必须是枚举对象中的其中一个,否则程序会抛出异常
  • toString() : 直接返回枚举对象的名称
  • ordinal():返回枚举对象在声明时的顺序,且顺序从0开始

九、注解

1. 理解Annotation

Annotation(注解)代码里的特殊标记,这些标记可以在编译、类加载、运行时被读取,并执行相应的处理。通过使用Annotation程序员可以在不改变原有逻辑的情况下,在源文件中嵌入一些补充信息。代码分析工具、开发工具和部署工具可以通过这些补充信息进行验证或者进行部署。
在JavaSE中,注解的使用目的比较简单,例如标记过时的功能,忽略警告等。在JavaEE/Android中注解占据了更重要的角色,例如用来配置应用程序的任何切而,代替JavaEEI旧版中所遗留的繁冗代码和XML配置等。JPA是基于注解的,Spring2.5以上都是基于注解的,
框架=注解+反射+设计模式

2. 使用实例

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.自定义注解

在这里插入图片描述

public @interface MyAnnotation {
    String value() default "hello"; //注解属性
    //String[] value(); 设置多个属性值
}
//注解的使用
@MyAnnotation(value = "hhh")
public Person(String name, int age) {
    this.name = name;
    this.age = age;
}

4. 元注解

元注解:对现有的注解进行解释说明的注解

  • Retention
    在这里插入图片描述

  • Target
    在这里插入图片描述
    jdk8新特性,Target新增两个成员变量,在Java8之前,注解只能是在声明的地方所使用,Java8开始,注解可以应用在任何地方。
    ElementType.TYPE_PARAMETER 表示该注解能写在类型变量的声明语句中(如:泛型声明)
    ElementType.TYPE_USE 表示该注解能写在使用类型的任何语句中

  • Documented:表示所修饰的注解在被javadoc解析时,保留下来

  • Inherited:被它修饰的 Annotation 将具有继承性

@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE,TYPE_PARAMETER,TYPE_USE})
public @interface MyAnnotation {
    String value() default "hello";
}

5. 可重复注解

//可重复注解的使用
//jdk8之前的写法:@MyAnnotations({@MyAnnotation(value="hi"),@MyAnnotation(value="hi")})
//jdk8之后新特性写法
@MyAnnotation(value="hi")
@MyAnnotation(value="abc")
public class Person{
}

//定义可重复注解
//1.在MyAnnotation上声明@Repeatable,成员值为MyAnnotations.class
//2.MyAnnotation的Target和Retention等元注解与MyAnnotations相同

//需要重复的注解
@Inherited
@Repeatable(MyAnnotations.class) //使用可重复注解的元注解
@Retention(RetentionPolicy.RUNTIME)
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
public @interface MyAnnotation {
    String value();
}

//注解数组注解
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
public @interface MyAnnotations {
    MyAnnotation[] value(); //将要重复的注解作为注解属性的类型
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值