Java面向对象编程

一、类和对象

对象

对象——用来描述一个客观事物的实体,由一组属性和方法构成;

属性——对象具有的各种你特征,比如收银员的年龄、身高、体重;

方法——对象执行的操作,比如收银员收银、打印账单、刷卡等;

类   ——具有相同属性和方法的一组对象的集合;类是对象的抽象,对象是类的具体;

类的方法——用来完成某个特定的应用程序功能,并返回结果;

public class Visitor {  //创建一个类
     public String name;
     public int age;

    // 定义方法
    public void bookTicket(){
        if(age >= 20 && age < 65){
            System.out.println(name + "的年龄是" + age + ",全票为20¥");
        }else if(age >= 12 && age < 20 ){
            System.out.println(name + "的年龄是" + age + ",半票票为10¥");
        }else{
            System.out.println(name + "的年龄是" + age + ",可免费参观");
        }
    }
}
public class VistorTest {
    public static void main(String[] args){
        Scanner scanner = new Scanner(System.in);
        String visName = "";
        int visAge = 0;
        do{
            System.out.print("请输入姓名:");
            visName = scanner.next();
            System.out.print("请输入年龄:");
            visAge = scanner.nextInt();

            Visitor v = new Visitor();
            v.age = visAge;
            v.name = visName;
            v.bookTicket();
        } while(!"n".equals(visName));
        scanner.close();
    }
}

方法传参(内存分配)

基本数据类型:在栈中进行分配;变量名指向具体的数值;变量在声明之后java就会立刻分配给他内存空间;基本类型之间的赋值是创建新的拷贝;“==”和“!=”是在比较值;基本类型变量创建和销毁很快; 引用数据类型:在堆中进行分配,堆的读写速度远不及栈;变量名指向存数据对象的内存地址,即变量名指向hash值;它以特殊的方式(类似C指针)指向对象实体(具体的值),这类变量声明时不会分配内存,只是存储了一个内存地址;对象之间的赋值只是传递引用;“==”和“!=”是在比较两个引用是否相同,需要自己实现equals()方法;类对象需要JVM去销毁;

构造方法

每个类都有一个默认的构造方法,如上例程序, 这种方法固定繁琐;使用带参构造方法就方便许多,编写了构造方法之后,会取代类默认的构造方法;

 

public class Voter {
    private static int count;
    private static final int total = 100;
    private String name;

    public Voter(String name){
        this.name = name;
    }
    ......          
}
public class main {
    public static void main(String[] args) {
        Voter zhang=new Voter("张三");
        Voter li = new Voter("李四");
        Voter wang = new Voter("王舞");
        ......
    }
}

 方法重载

public class Add {

    public int addSum(int num1, int num2){
        return (num1 + num2);
    }
    public int addSum(int num1, int num2, int num3){
        return (num1 + num2 + num3);
    }

    public double addSum(double num1, double num2){
        return (num1 + num2);
    }
    public double addSum(double num1, double num2, double num3){
        return (num1 + num2 + num3);
    }
}
public class Calc {
    public static void main(String [] ages){
        int [] a = new int[5];
        int [] s = new int[9];
        Add sum = new Add();
        System.out.println(sum.addSum(2.2, 3.3));
        System.out.println(sum.addSum(3, 5));
        System.out.println(sum.addSum(3, 5, 3.3));
        System.out.println();
    }
}

this关键字

调用属性

this.health = 170;
this.name = "张三”

调用方法

this.print();

调用构造方法

this();         // 如果使用,必须是构造方法中的第一条语句
this(“小黑”, 100, 100, “雄”); 

二、封装和继承

 封装

封装就是讲某些信息影藏在类内部,不让外部程序直接访问,而是通过该类提供的方法来实现对内部影藏信息的操作和访问;

封装的好处:防止属性被错误修改;有利于提高系统之间的松耦合,提高系统的独立性;提高软件的可重用性;降低构建大型系统的风险;

封装原则:①把尽可能多的东西藏起来,对外提供接口;②把所有的属性隐藏起来;

封装步骤:①修改属性的可见性(设为private);②创建公有的getter/setter方法;③在getter/setter方法中加入属性控制语句;

/**
 * 标准javaBean的创建过程
 */
public class JavaBean {
    // 第一步:创建私有属性
    private String name;
    private int ID;
    private int age;
    private String address;

    // 第二步:生产getter和setter方法
    public String getName() {
        return name;
    }

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

    public int getID() {
        return ID;
    }

    public void setID(int ID) {
     if (ID < 0)
       ID = 0
this.ID = ID; } public int getAge() { return age; } public void setAge(int age) {
     if (age < 0)
       age = 0
this.age = age; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } // 第三步:创建无参构造函数和有参构造函数 public JavaBean() { } public JavaBean(String name, int ID, int age, String address) { this.name = name; this.ID = ID; this.age = age; this.address = address; } @Override public String toString() { return "JavaBean{" + "name='" + name + '\'' + ", ID=" + ID + ", age=" + age + ", address='" + address + '\'' + '}'; } }

包的使用

JDK包提供:①java.lang:虚拟机自动引入;② java.util:提供一些实用类;③ java.io:输入、输出; 

为了使用不在同一个包中的其他类,需要在程序中使用 import 关键字导入这个类;

package com.ibeifeng.java.oop.javabean;

import com.ibeifeng.java.oop.buytickets.Visitor;     // 导入buyticket包中的Visitor类

public class User {
    public static void main(String [] args){
        Visitor user = new Visitor();
        user.name = "李四";
        user.age = 22;
        user.bookTicket();
        // 当前包与导入包如果有重名,name都要使用全路径,
        // 如果不使用全路径,那么默认的是导入的类;
//        Visitor user1 = new Visitor();
        com.ibeifeng.java.oop.javabean.Visitor user1 = new com.ibeifeng.java.oop.javabean.Visitor();
        user1.name = "张三";
        user1.age = 55;
        user1.bookTicket();
    }
}

 成员变量访问权限控制

通过关键字修饰变量,从而控制访问权限

三、继承和多态

static关键字

 静态变量在内存中只有一块控件,而实际变量,每次事例都会重新开辟内存空间;

当静态变量不同时,根据定义顺序先后执行;

当静态变量和代码快中的变量相同时,先定义再赋值;

实例方法可以直接调用静态方法,但静态方法不能直接调用实例方法,必须使用new实例化后,在调用。实例方法中不能定义静态变量,

 静态代码块:初始化静态变量

构造方法:初始化实例变量

 继承

把共性或重复的属性方法单独提取出来,用类来封装,对于个性则不提取,各自保留;

继承就是把父类的所有属性和方法继承过来;

被继承的类是父类,主动继承的类是子类,子类(A)使用关键字extends继承父类(B)

单根性——java中只支持单根继承,即一个类智能有一个直接父类

public class A extends B(){}     // A继承父类B

传递性——A继承B,B继承C,那么A继承了C,即一个类可以间接有多个父类

子类可以继承父类,并且可以有自己的特性,但是父类不可以继承子类

this:本类对象

super:父类对象

 当实例化子类时,都会先执行父类的无参构造方法

如果父类有有参构造函数,则必须显示提供无参构造函数;

指定调用父类的有参构造函数,使用 super 关键字:

Public A(string name){
  super(“小王”);          
  System.out.println("子类的有参构造方法:” + name);  
}

super关键字来访问父类的成员:

  • super只能出现在子类的方法和构造发放中;
  • super调用构造方法时,只能是第一句;
  • super不能访问父类的 private 的成员;
public class Comm {
    private String name;
    private String gender;
    private int healthValue;
    private int loveValue;
    ......
    public void show(){
        System.out.println("宠物的自白:");
        System.out.println("我的名字叫:" + name + ",我的性别是:" + gender + ",健康值为" + healthValue + ",和主人亲密度为" + loveValue);
    }
}
public class Dog extends Comm {
    public Dog(String name, String gender, int healthValue, int loveValue) {
        super(name, gender, healthValue, loveValue);
    }
}

多态

 目的:为了避免方法重写;

方法重写(覆盖)

  • 建立在继承的基础之上;
  • 类根据需求对从父类继承的方法进行重新编写;
  • 重写时,可以用super,方法的方式来保留父类的方法;
  • 构造方法不能被重写;

方法重载:

  • 方法名相同;
  • 参数列表不能相同;
  • 与返回值类型无关;

当子类继承父类(show方法),并且想输出父类之外的属性,那么子类只能重写父类的show方法,当实例化之后,使用的只能是子类的方法;

方法重写规则:

  • 方法名相同;
  • 参数列表相同;
  • 返回值类型相同或是其子类
  • 访问权限不能严于父类
  • // 报错
    public void show(){ ... }     // --> 父类
    protected void show() { ... }    // --> 子类

    父类的静态方法不能被子类覆盖为非静态方法,反之亦然;

  • 子类可以定义于父类同名的静态方法,以便在子类中隐藏父类的静态方法;
  • 父类的私有方法不能被子类覆盖;
  • 不能抛出比父类方法更多的异常;
public class Comm {
    private String name;
    private String gender;
    private int healthValue;
    private int loveValue;
    ......
    public void show(){
        System.out.println("宠物的自白:");
        System.out.println("我的名字叫:" + name + ",我的性别是:" + gender + ",健康值为" + healthValue + ",和主人亲密度为" + loveValue);
    }
}
public class Dog extends Comm {
    private int age;

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Dog(String name, String gender, int healthValue, int loveValue) {
        super(name, gender, healthValue, loveValue);
    }

    public void show(){
        System.out.println("宠物的自白:");
        System.out.println("我的名字叫:" + getName() + ",我的性别是:" + getGender() + ",现在" + age + "岁"  + ",健康值为" + getHealthValue() + ",和主人亲密度为" + getLoveValue());
    }
}

 

 

四、抽象类和接口

 

 

五、异常

异常的三种情况

  • ①正常情况:正常执行,不进入catch块;
  • ②出现异常:进入catch块,输出异常;
  • ③异常类型不匹配:异常类型与catch类型不一致,会中断程序;

常用异常输出语句

  • 调用方法输出异常信息:ex.printStackTrace();

异常对象常用方法

  • void printStackTrace():输出异常的堆栈信息
  • StringgetMessage():返回异常信息描述字符串,是printStackTrace()输出信息的一部分;
public class TryCatch {
    public static void main(String[] args) {
        new TryCatch().div(10, 0);
    }
    public void div(int a, int b){
        int sum = 0;
        try {
            sum = a / b;
        }catch (Exception ex){
            ex.printStackTrace();
        }
        System.out.println(a + "/" + b + "=" + sum);
    }
}

常用的异常类

一旦被异常父类(Exception)捕获,其他的catch块都不会值执行 ,如果子类异常位于父类异常之前,那么父类异常将不会执行(相当于重写了父类异常);

try...catch..finally:finally块一般放置程序最后,放置总是会执行的代码;

注意捕获异常时的顺序

  • 先捕获子类异常,最后再捕获父类异常;

观察异常技巧:

  • 在控制台查看异常时,先解决最后一个异常,从下往上查看时,先查看自己写的代码(蓝色部分)

 finally唯一不执行的情况:

  • catch块中 执行 System.exit();代码;
  • try 必须执行,catch 和 finally 至少要执行一个;

return在异常中的执行顺序:

  • 先执行 catch 块,然后跳转到 finall, 最后跳转到 return,退出程序;

 

throws 和 throw的区别

java异常处理的throw和throws的区别 - 刘要直 - 博客园 https://www.cnblogs.com/liuyaozhi/p/5812700.html

Java中关键字throw和throws的区别 - CSDN博客 https://blog.csdn.net/hjfcgt123/article/details/53349275

 

输入输出处理

Java流

 

posted @ 2018-08-06 23:41  Merlin·Fan  阅读(311)  评论(0编辑  收藏  举报