2020年java面向对象编程oop课堂笔记

面向对象编程

1. 什么是面向对象

  • 面向过程思想
    • 步骤清晰简单,第一部做什么,第二部做什么…
    • 面向过程适合处理一些较为简单的问题
  • 面向对象思想
    • 物以类聚,分类的思维模式,思考问题首先会解决问题需要哪些分类,然后对这些分类进行单独思考。最后,才对某个分类下的细节进行面向过程的思索。
    • 面向对象适合处理复杂的问题,适合处理需要多人协作的问题。

​ 对于描述复杂的事物,为了从宏观上把握、从整体上合理分析,我们需要使用面向对象的思路去处理。

  • 面向对象的本质:以类的方式组织代码,以对象的组织(封装)数据。

  • 三大特性

    • 封装:
    • 继承
    • 多态

2. 类与对象的创建

一个类由n个属性和n个方法组成

创建与初始化对象

  • 使用new关键字创建对象
  • 使用new关键字创建的时候,除了分配内存空间之外,还会给创建好的对象进行默认的初始化以及对类中构造器的调用。
  • 类中的构造器也称为构造方法(分为无参构造有参构造,且无参构造在没有主动创建构造器时,默认存在),是进行创建对象的时候必须调用的。
  • 构造器有以下特点:
    • 必须和类的名字相同
    • 必须没有返回类型,也不能写void
    • 构造方法中不能用return返回值,但可以用return作为方法的结束

构造器

  1. 和类名相同,权限修饰符一般只能是public
  2. 没有返回值

作用:

  1. new 本质在调用构造方法
  2. 初始化对象的值

注意点:

  1. 如果没有显式定义任何构造方法,默认调用无参构造
  2. 定义有参构造之后,必须显式地定义无参构造

实例代码

public class Person{

    //无参构造
    private String name;
    private  int age;

    public Person() {
        System.out.println("这是无参构造!");
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
        System.out.println("这是有参构造:"+name+"今年"+age+"岁了。");
    }

}

class TestAre{
    public static void main(String[] args) {
        new Person();
        new Person("阿凡",20);
    }
}

3. oop小结

1.类与对象
  类是一个模板:抽象 对象是一个具体的实例
2.方法
   定义与调用
3.对象的引用
   引用类型:对象通过引用来操作
4.属性:也叫成员变量
  默认初始值:
    数字:0 0.0
    char:u0000
    boolean:false
    引用:null
    修饰符 属性类型 属性名 = 属性值!
5.对象的创建和使用
    必须使用new关键字创造对象,构造器
    对象的属性 person.name
    对象的方法 person。sleep()
6.类:
    静态的属性  属性
    动态的行为  方法
    - 封装 继承 多态 -
   

4. 封装

  • 该露的露,该藏的藏

    • 我们程序要追求“ 高内聚,低耦合”。
      1. 高内聚就是类的内部数据操作细节自己完成,不允许外部干涉;
      2. 低耦合:仅暴露少量的方法给外部使用。
  • 封装

    • 禁止直接访问某一个对象中数据的实际表示,而应通过操作接口来访问,这称为信息隐蔽
  • 总言:属性私有,get/set

实例代码

public class Person{
    private String name;
    private int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        if(age <=120 && age >= 0){
            this.age = age;
        }else{
            System.out.println("年龄不合实际");
        }
    }
}

class TestAre{
    public static void main(String[] args) {
        Person person = new Person();
        person.setAge(30);
        System.out.println(person.getAge());
    }
}

5. 继承

  • 关键字extends,所有类默认继承object类
  • 继承的本质是对某一批类的抽象,从而实现对现实世界更好的建模。
  • java类中只有单继承,没有多继承!即一个类只有一个直接父类
  • 子类继承父类,会自动拥有父类所有public,protected,默认修饰符修饰的属性和方法(不能继承或重写父类的私有成员,构造器,静态方法,final方法)。

实例代码

public class Person  {
    private String name;
    private char sex;
    public void say(String name,char sex){
        System.out.println("我叫"+name+",性别"+sex);
    }

}

class Man extends Person{
    public static void main(String[] args) {
        Man man = new Man();
        man.say("阿凡",'男');
    }
}

6. this和super注意点

this用法:

形式参数可以被认为是局部变量

  1. 用this关键字调用成员变量,防止与局部变量名称冲突
  2. 用this关键字调用该类中其他成员方法(this可以省略)
  3. 用this([参数1,参数2,…])调用该类中的构造方法:
    • 只能在构造方法中使用this调用其他构造方法,不能在成员方法中使用
    • 在构造方法中使用this调用其他构造方法的语句只能写在第一句
    • 不能在一个类的两个构造方法中使用this互调

super用法:

  1. 使用super来调用父类的成员变量和方法,构造方法

super.成员变量

super.成员方法

super([参数1,参数2,…])

  1. 通过super调用父类构造方法的语句只能出现在子类构造方法的第一行,并且只能出现一次

super VS this:

  • 代表的对象不同:
  • this:本身调用这个对象
  • super:代表父类对象的应用
  • 前提:
    • this:没有继承也可以使用
    • super:只能在继承条件才可以使用
  • 构造方法
    • this():本类的构造
    • super():父类的构造

注意:

  1. 在构造方法中,this与super不能同时出现

  2. static静态方法中不能使用this和super

  3. super可以调用父类的静态方法

实例代码

//person类
public class Person  {
    private String name = "person";

    public void print(){
        System.out.println("阿凡person");
    }
}
//student类  继承  person类
class Student extends Person{
    private String name = "阿凡student";
    public void test1(){
        print();  //阿凡student
        test();   //阿凡person
        super.print();  //阿凡person
    }
    public void test(){
        System.out.println(name);   //阿凡student
        super.print();    //阿凡person
    }
    public void print(){
        System.out.println(this.name);
    }
}
//测试类
class TestAre{
    public static void main(String[] args) {
        new Student().test();
        new Student().test1();
    }
}

7. 重写

重写:需要有继承关系,子类重写父类的方法!

  1. 方法名、参数列表、返回值类型必须相同
  2. 子类重写父类方法时,不能使用比父类被重写的方法更严格的访问权限

修饰符访问权限大小:public>protected>default>private

  1. 抛出的异常:范围可以被缩小,但不能扩大:

classNotFoundException(小) -->Exception(大)

为什么需要重写:

  1. 父类的功能,子类不一定需要,或者不一定满足!
  2. Alt + Insert : @override
//person类
public class Person  {
  private String name = "阿凡公民";
  public void print(){
      System.out.println(name+"去上班!!");
  }
}


//student类 继承与 person类
class Student extends Person{
  private String name = "阿凡同学";
  @Override
  public void print(){  //重写print方法
      System.out.println(name+"去上学!!");
  }
}

class TestAre{
    public static void main(String[] args) {
        new Student().print();  //阿凡同学去上学!!
    }
}

8. 多态

定义:不同类的对象在调用同一方法时所呈现出的多种不同行为。

优点:提高了程序的可拓展性和可维护性。

  • 多态一般在接口被实现或类被继承时使用

  • 对象的类型转换:

    • 父类引用子类对象时**(向上转型),不能通过父类变量去调用子类特有方法**
    • 将父类引用对象强制转换为子类时**(向下转型)**,尽量用instanceof判断一个对象是否是某个类(或接口)的实例或子类对象。

    对象 instanceof 类(或接口)

instanceof 用来测试一个对象是否为一个类的实例
boolean result = obj instanceof class
注意点:
  1. obj必须为引用类型,不能为基本类型
  2. obj可以为null
  3. obj可以为class类的直接或间接子类
  4. obj可以为class接口的实现类

实例代码

//Person类
public abstract class Person {
    public abstract void work();
}
//老师类继承Person类
class Teacher extends Person{
    @Override
    public void work() {
        System.out.println("老师上课");
    }
    //老师特有方法
    public void write(){
        System.out.println("老师写教案");
    }
}
//医生类继承Person类
class Doctor extends Person{
    @Override
    public void work() {
        System.out.println("医生看病");
    }
    //医生特有方法
    public void operation(){
        System.out.println("医生做手术");
    }
}
//测试类
class Test{
    public static void main(String[] args) {
        Person p1 = new Teacher();
        Person p2 = new Doctor();
        p1.work();  //老师上课
        p2.work();  //医生看病
        if( p1 instanceof Teacher){  //判断p1是否是Teacher类的对象
            Teacher teacher = (Teacher)p1;
            teacher.write(); //老师写教案
        }
        else{
            Doctor doctor = (Doctor)p2;
            doctor.operation();
        }
    }
}

9. final关键字

final关键字可以修饰类、变量、方法:

  1. final修饰的类不能被继承

  2. final修饰的方法不能被子类重写

  3. final修饰的变量(成员变量局部变量)是常量,只能被赋值一次

    注意:

    成员变量被final修饰时,声明变量的同时必须初始化赋值

    局部变量被final修饰时,可以先声明,再赋值一次

10. static关键字

static用于修饰类的属性,方法,代码块等,称为静态Xxx

static只能修饰成员变量,不能修饰局部变量

注意点:

  • 静态变量(也叫全局变量)可以被该类的所有实例对象共享

类名.变量名

  • 在同一类中,成员方法可以直接调用静态方法,但是静态方法不能直接调用成员方法,必须创建对象后才能访问成员方法

类名.静态方法();

或者

实例对象名.静态方法();

  • 静态代码块在类第一次被new 对象 实例化后才会被执行,且只会执行一次,一般用来加载初始化信息。

static{

}

**static和final同时使用 **

  1. static final用来修饰成员变量和成员方法,可简单理解为“全局常量”!

  2. 对于变量,表示一旦给值就不可修改,并且通过类名可以访问。

  3. 对于方法,表示不可覆盖,并且可以通过类名直接访问。

实例代码

class Student{
    private  static int age;
    private double score;

    public static void main(String[] args) {
        Student s1 = new Student();
        System.out.println(Student.age);
        System.out.println(s1.age);
        System.out.println(s1.score);
    }
}

静态代码块

实例代码

public class Person {
    //赋初始值
    {
        System.out.println("匿名代码块");
    }
    //只执行一次
    static{
        System.out.println("静态代码块");
    }

    public Person(){
        System.out.println("构造方法");
    }

    public static void main(String[] args) {
        new Person();
    }

}

11. 抽象类

  • 关键字:abstract 抽象类,属于类 单继承 (接口是多继承)
  • abstract修饰的抽象方法只有方法名字,没有方法的实现!
  • 注意点
    • 抽象类中的成员变量定义没有要求
    • 包含抽象方法的类必须定义为抽象类
    • 抽象类不能new出来,只能靠子类实现
    • 抽象类中可以写普通方法,包括静态方法
    • 抽象方法必须写在抽象类中,但抽象类可以没有抽象方法

12. 接口

接口:只有规范,比抽象类更严格,是抽象类的特殊形式

public interface 接口名{

}

作用

  1. 接口里面定义的成员变量都是 public static final修饰,只能是常量,必须赋初始值
  2. 接口中的成员方法只能是抽象方法。默认修饰符 public abstract,但public abstract可以省略不写。
  3. 注意:接口不可以有构造方法,但抽象类可以
  4. 接口不能实例化,接口中没有构造方法,其他类使用implements 可以实现多个接口,
  5. 必须要重写接口中的所有方法
  6. 接口中的成员方法权限只能且都是public
  7. 接口是多继承

实例代码

public interface Animal {
    void shout(String name);
}

class Cat implements Animal{

    @Override
    public void shout(String name) {
        System.out.println(name + "在喵喵叫!");
    }
}

class Dog implements Animal{
    @Override
    public void shout(String name) {
        System.out.println(name+"在汪汪叫!");
    }
}

class AnimalTest{
    public static void main(String[] args) {
        Animal a1 = new Cat();
        Animal a2 = new Dog();
        a1.shout("猫");
        a2.shout("狗");
    }
}

13. 4种内部类

非常重要内部类不能有静态方法或属性。

成员内部类

外部类名 对象名 = new 外部类名();

外部类名.内部类名 变量名 = new 外部类名().内部类名();

注意:

  • 在成员内部类中,内部类可以直接(不用new 外部类创建对象)调用外部类的所有属性+方法(包括静态和非静态)。
  • 在外部类中,不可以直接调用内部类中的属性+方法,但可以创建内部类对象后调用。

实例代码

//person类  外部类
public class Person {
    
    String name = "Afan";
    int age = 20;
    
    public void doSomething(){
        System.out.println("AFan在吃饭!");
    }
    public void say(){
        Heart heart = new Heart();
        heart.fleed();
        System.out.println("AFan说你好!");
    }

    //心脏 成员内部类
    class Heart{
        
        public void jump(){
            System.out.println("心脏跳动!!");
            doSomething();//直接调用外部类方法
            say();
        }
        public void fleed(){
            System.out.println("血在流");
        }
    }
}

class Test{
    public static void main(String[] args) {
        Person person = new Person();
        Person.Heart heart = person.new Heart();
        heart.jump();
        heart.fleed();
    }
}

局部内部类

也叫方法内部类,在方法中定义,有效范围只限于方法内部,等同于局部变量。

注意:

  • 局部内部类可以在new 外部类对象后调用外部类的属性+方法
  • 局部内部类可以 直接调用 自身在外部类中所在方法里的局部变量。
  • 只有在创建局部内部类的方法中才可以创建局部内部类的对象,并调用内部类的所有属性+方法。

实例代码

/person类
public class Person {
    String name = "Afan";
    int age = 20;
    
    public void doSomething(){
        System.out.println("AFan在吃饭!");
    }
    public void say(){
        System.out.println("AFan说你好!");
    }

    public void produce(){
        
        String product_name = "电脑";
        //产品类 局部内部类
        class Production{
           // String product_name = "电脑";
            public void use(){
                Person person = new Person();  //外部类对象
                person.doSomething();
                System.out.println(product_name+"的使用");
            }
        }
        Production production = new Production();
        production.use();
    }
}

class Test{
    public static void main(String[] args) {
        Person person = new Person();
        person.produce();

    }
}

静态内部类

本质:使用static关键字修饰的成员内部类

  • 静态内部类只能直接调用外部类中的静态属性和静态方法
  • 其他类需要调用静态内部类的属性和方法时,可以跳过外部类,直接new 内部类对象来访问其成员。

外部类名.静态内部类名 对象名 = new 外部类名.静态内部类名();

实例代码

//person类
public class Person {
    static String name = "Afan";

    public static void doSomething(){
        System.out.println("AFan在吃饭!");
    }
    public void say(){
        System.out.println("AFan说你好!");
    }

    //心脏类 就在成员内部类前面加个static
    static class Heart{

        public  void jump(){
            doSomething();

           // Person person = new Person(); 访问非静态成员必须创建对象。
            //person.say();

            System.out.println(name+"的心脏在跳动!!");
        }
    }
}
class Test{
    public static void main(String[] args) {
        Person.Heart heart = new Person.Heart();
        heart.jump();
    }
}

匿名内部类

java类调用某个方法时,如果该方法的参数类型是接口类型,那么除了传递一个接口的实现类,也可以使用匿名内部类实现该接口来作为该方法的参数。(开发中常用)

[修饰符] 方法名(new 父类名或者接口名(){
    // 方法重写
    @Override 
    public void method() {
        // 执行语句
    }
};)

实例代码

//接口类
public interface Animal {
    void shout(String name);
}

class AnimalTest{
    String name;
    public void animalShout(Animal animal){
        animal.shout(name);
    }
    public static void main(String[] args) {

      AnimalTest a1 = new AnimalTest();
      a1.name = "猫";
      //匿名内部类
      a1.animalShout(new Animal() {
          @Override
          public void shout(String name) {
              System.out.println(name+"在叫!!!");
          }
      });
    }
}

JDK8的Lamabda表达式

使用条件:只适用于在匿名内部类中只有一个抽象方法的接口实现,简化代码。

([数据类型1 变量名1,数据类型2 变量名2,…]) ->{表达式主体}

注意点:

  1. 参数列表只有一个参数时可以省略”()“和变量的数据类型
  2. 表达式主体只有一条语句时,可以省略主体的大括号
  3. 表达式主体可以有return返回值,当只有一条return语句,可以省略return

实例代码

//接口类
public interface Animal {
    void shout(String name);
}
class AnimalTest{
    String name;
    public void animalShout(Animal animal){
        animal.shout(name);
    }
    public static void main(String[] args) {

      AnimalTest a1 = new AnimalTest();
      a1.name = "小猫";
      //Lamabda表达式
      a1.animalShout(name ->
              System.out.println(name+"在叫!!!")
      );
    }
}

进一步简化Lamabda表达式(了解)

使用条件:Lamabda表达式主体只有一条语句

用法:程序省略主体的大括号,用英文双冒号“::”来引用方法和构造器

Lamabda表达式对普通方法和构造方法的引用形式

种类对应的引用示例
类名引用普通方法类名::类普通方法名
类名引用静态方法类名::类静态方法名
对象名引用方法对象名::实例方法名
构造器引用类名::new

14. 异常

定义:程序在编译、运行过程中出现的非正常状况

  java的异常类都继承于java.lang.Throwable类

Throwable的继承体系

[外链图片转

  • Error类:错误类,比较严重(了解)
  • Exception类:异常类,程序本身可以处理,java开发中进行的异常处理都是针对Exception类及其子类

Throwable类常用方法

方法说明功能描述
String getMessage()返回此throwable的详细消息字符串
void printStackTrace()打印完整的异常信息

处理异常的两种方式

  1. 使用try…catch语句对异常进行捕获处理

    try{
      //可能发生异常的语句
    }catch(Exception类或其子类 e){
       e.printStackTrace(); //打印输出异常原因
       //对捕获的异常做相应处理
    }finally{
       //无论程序是否异常都必须执行的语句
    }
    

    实例代码

    public class Example {
        public static void main(String[] args) {
           int result = divide(4,0);
           if(result == -1){
               System.out.println("程序出现异常");}
            else{
               System.out.println(result);   
           }
        }
        //运行结果:出现的异常:/ by zero
        //        无论程序是否异常都必须执行的finally语句
        //        程序出现异常
        
        //除法运算
        public static int divide(int a,int b){
            try{
                int result = a/b;
                return  result;
            }catch(Exception e){
                System.out.println("出现的异常:"+e.getMessage());
            }finally{
                System.out.println("无论程序是否异常都必须执行的finally语句");
            }
            return -1; //如果程序异常,返回-1
        }
    }
  2. 使用throws抛出异常,等以后再处理有可能的异常,

    [修饰符] 返回值类型 方法名([参数列表]) throws Exception{
       //方法体
       }
    

    有可能出现异常的方法加上throws关键字后,其他类调用它时首先要处理完异常之后才能使用该方法。

实例代码

public class Example {
    public static void main(String[] args) {

       try {
           int result = divide(4, 0);
           System.out.println(result);
       }catch(Exception e){
           System.out.println("出现异常:"+e.getMessage());
       }

    }
    //运行结果:出现异常:/ by zero

    //除法运算
    public static int divide(int a,int b) throws Exception{
        int result = a/b;
        return result;
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
开发阳光旅行网app中用户下单功能,可实现用户添加订单并完善出行人信息、修改订单,删除订单以及打印行程信息等功能。 具体功能要求如下: (1)显示系统主菜单 包括添加出行订单、查看我的出行订单、修改订单信息、删除出行人、查看行程、退出系统6项功能,其他功能本项目不做要求,当用户选择功能编号后可进入执行相应功能。执行结果如图1所示。 图1 主菜单 (2)添加出行订单 填写出行日期、联系人手机号码、循环录入出行人信息。 出行人信息包括:  出行人类别:成人、儿童(1.2m以下)、老人(65岁以上)  姓名  年龄(如选择类别为老人,输入年龄不足65岁的,显示提示信息“对不起,老人订单年龄需为65岁以上!”)  如果是儿童,需确定是否占床 每成功录入一条出行人信息后,显示出其详细信息,并计算出行金额。定价如下:  成人:2000元/人  儿童:免费,如需占床另加30元  老人:半价,即1000元/人 当一条出行人信息录入完毕后,提示“是否继续添加(Y/N)?”,此处不区分大小写,当输入y或Y时继续录入下一条,否则显示订单信息,包括:  出行日期  联系人手机号码  订单总金额(即所有出行人定单金额之和) 最后显示主菜单。执行效果如图2所示。 图2 添加出行订单 (3)查看我的出行订单信息 查看我的出行订单:查看所录入的订单信息。包括出行日期、联系人手机号码、所有出行人信息,运行效果如图3所示。 图3 查看我的出行订单 (4)修改行程信息 可修改出行日期、联系人手机号码,要求手机号码必须为11位,否则抛出异常信息,提示“手机号码必须为11位”,运行效果如果4所示。 图4 手机号码不是11位 正确修改后,显示修改后的信息,并提示“修改成功!”。如图5所示。 图5 修改订单成功 (5)删除出行人 填写要删除的出行人姓名,执行删除操作,删除成功后给出提示“删除成功!”,如图6所示。如果输入姓名错误,则提示“对不起,定单中不包含此游客信息!”如图7所示。 图6 删除出行人成功 图7 删除出行人失败 (6)查看行程 显示本次旅行行程信息。即读取“旅游行程.txt”文件(素材提供),显示在控制台。运行效果如图8所示。 图8 查看行程 (7)退出系统 退出当前系统,显示“欢迎下次再来。”如图9所示。 三、要求与实现步骤 (一)不使用数据库,使用对象和集合存储数据 (二)定义实体类(成人订单、儿童订单、老人订单),儿童订单、老人订单为成人订单的子类。实体类至少包含但不局限于以上3个。 (三)在各实体类中均需实现各自计算订单价格、显示订单信息的方法,使用方法的重写。 (四)定义工具类,实现查看我的出行订单、添加订单、修改行程信息、删除出行人、查看行程等方法。需使用到对象传参。 (五)使用泛型集合存储所有出行人信息,使用集合的遍历实现查看订单信息、统计订单总金额、删除出行人等功能。 (六)显示信息时,只有儿童出行人需显示是否占座,需使用面向对象多态实现。 (七)修改行程信息时,当手机号码录入错误时需使用throw手动抛出异常。 (八)使用I/O技术实现文件的读取功能,将文本文件“行程信息.txt”中的内容显示到控制台。 (九)定义测试类,完成项目功能菜单以及整体流程,调用相应方法实现具体功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值