006-面向对象,继承,方法重写,访问修饰符详解,final,多态,抽象类,接口,图书管理系统

面向对象

面向对象是一种思想

面向过程    注重的是“步骤”

面向对象    注重的是“对象”

对象

对象:具有明确的属性和行为(功能)的实体

猫类、狗类、人类
类:是一组具有相同属性和行为的对象的集合

        属性                      行为

人    姓名、性别、年龄、身高        唱歌、跳、rap、打篮球

车     颜色、品牌、价格、轮子个数       载人、加速、减速....

猫    年龄、性别、姓名、品种、颜色      喵喵、找老鼠、上树......


类有两个组成部分:
1、属性   ------->  成员变量
2、行为   ------->  成员方法

类和对象的关系

1、对象是具体的,类是抽象的
2、面向对象就是  从具体到抽象,从抽象到具体的过程

如何创建类

1、确定类名
2、成员变量
3、成员方法

Student类

public class Student {
    //属性=====成员变量  (写在类的里面,方法的外面的变量)
    String name; //姓名
    int  age;//年龄
    double height;//身高
    char sex ;//性别
    String address;//住址

    //行为=====成员方法
    public  void study() {
        System.out.println(name+"学习~~~~~~~~~~~");
    }

    public void sleep() {
        System.out.println("睡觉~~~~~~~~~~");
    }

}

如何创建对象

1、创建对象
类名  变量名(对象名) = new 类名();

2、通过对象去调用类的属性
对象名.属性名

3、通过对象去调用类的方法
对象名.方法名()



要想调用一个类的方法和属性,必须要先要创建这个类的对象

测试类

public class Test {
    public static void main(String[] args) {
        //创建Student对象  类名  变量名(对象名) = new 类名();
        Student stu  = new Student();

        //调用对象的属性(成员变量)   存值 
        //属性的功能   存值   取值
        stu.name = "cxk";
        stu.age = 30;
        stu.sex = '男';
        stu.height = 180;
        stu.address = "武汉";

        //调用对象的属性    取值
        System.out.println("姓名为:"+stu.name);
        System.out.println("年龄为:"+stu.age);

        //调用对象的方法   对象名.方法名();
        stu.study();
    }
}

成员变量和局部变量

区别:
1、定义的变量位置不同
    a、定义在类中,方法外的变量称之为成员变量
    b、定义在方法中的变量称之为局部变量
2、作用域不相同(本类)
    a、成员变量,在整个类中都能被访问
    b、局部变量,只能在变量所在大{}中被使用
3、初始值(默认值)不同
    a、成员变量,系统会赋予默认值
    b、局部变量,没有默认值(所以要注意:局部变量必须要赋值才能使用)
4、重名问题
    a、成员变量不能重名
    b、局部变量可以在不同的作用域中定义重名变量
5、就近原则
    当成员变量和局部变量名相同的时候,使用的时候采用就近原则

6、生命周期不同
    a、成员变量  是随着对象在堆内存中,对象被销毁,成员变量被销毁
    b、局部变量  因为局部变量在栈内存中,当方法执行完成之后,就会被销毁

测试

1、设计个图形类,设计两个方法,一个求周长(返回周长),一个球面积(返回面积)

  • 代码实现
public class Rectangle {
    //成员变量
    double length;
    double width;

    //成员方法
    public double area() {
        return length *width;
    }
    public double perimeter() {
        return (length + width )*2;
    }
}

public class Test {
    public static void main(String[] args) {
        //1、创建Rectangle对象
        Rectangle r = new Rectangle();

        //2、给对象的属性赋值 (调用对象的属性)
        r.length = 30;
        r.width = 20;

        //3、求面积和周长       (调用对象的方法)
        double mj = r.area();
        System.out.println("面积为"+mj);
        double zc = r.perimeter();
        System.out.println("周长为"+zc);
    }
}

面向对象编程(OOP)

封装、继承、多态

封装

面向对象中的封装
隐藏类的实现细节,对外提供公共的方法。
1、私有化属性
2、对外提供公共的方法       setter/getter
private   私有的   只能在本类中使用

代码演示

public class Dog {
    private String name;
    private int age;
    private char sex;

    //alt + shift + s  ------- >  getters/setters

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public char getSex() {
        return sex;
    }
    public void setSex(char sex) {
        this.sex = sex;
    }
}

this关键字

this关键字的含义是:当前类的对象
this关键字的用法

调用属性
    this.属性名

调用方法
    this.方法()

调用构造方法(使用的很少)
    this();
    this(构造参数。。。。);
    注意:调用类的构造方法,要方法第一行代码

当如果没有变量名冲突的时候,this关键字是可以省略的。

构造方法

构造方法就是创建对象的方法
构造方法
    语法:
    访问修饰符 方法名(){

    }
    访问修饰符:public
    方法名:必须与类名一致(区分大小写)
    ()  :构造参数列表

如果一个类没有定义构造方法,那么系统会默认给这个类提供一个无参构造方法
如果这个类定义了构造方法,那么系统不再提供无参构造

继承

为什么要继承

为了解决代码的重用性

如何继承

1、编写父类
2、编写子类
3、让子类继承自父类

继承的语法:
public class 子类 extends 父类{


}

继承之后特点(好处)

1、子类继承父类,那么子类可以享有父类的非私有属性和方法
2、子类也可以有自己独有的属性和方法
3、在java中只支持单继承(一个父类可以有多个子类,但是一个子类只能有一个父类),可以多层继承
4、在java中最顶端的类叫做 Object类,  在java中如果一个类没有继承任何的父类,那么默认继承自Object类

父类和子类之间的关系

在程序中
被继承的类   称之为   父类、超类、基类
继承类      称之为    子类、派生类

子类  is   a   父类

子类的创建过程

子类在创建对象的时候,会先去创建父类的对象

如果在父类中加入一个有参构造,那么子类就会报错
原因:因为父类中有了有参构造,那么系统不会去提供无参构造,子类在创建的是,默认又去调用了父类的无参构造

创建对象的同时对属性进行赋值

在子类中创建有参的构造方法
public Student(String name,int age) {
    //调用父类的构造方法
    super(name,age);
}
在父类中创建有参构造
public Person(String name,int age) {
    this.name = name;
    this.age = age;
}

super关键字

super  表示直接父类对象

super  关键字的作用
    调用父类的属性、方法、构造方法

    调用父类的属性:super.属性名
               如果字类中没有这个属性,那么调用的是父类的属性
               那么使用this.属性名、super.属性名,表示都是一样的
    调用父类方法: super.方法名
                如果子类中没有这个方法,那么调用的是父类的方法
                如果子类中有相同的名字的方法(方法的重写)
    调用父类的构造方法: super(构造方法)

    必须要写在构造方法的第一行代码

方法重写

在子类中出现与父类有相同签名的方法,就叫做方法的重写

重写的要求:
    重写的方法  方法名、返回值类型、参数列表要一致,访问修饰符要比父类的大


父类Person中work方法
public void work() {
    System.out.println("这是父类的work方法");
}
在子类中重写父类的work方法

    @Override
    public void work() {
        //super.work();
        System.out.println("喝水");
        System.out.println("抽根烟");
        System.out.println("工作");
        System.out.println("看看时间");
        System.out.println("下班");
    }    


@Override    注解      检测这个方法是否方法重写

方法重写与方法重载的区别

类型 位置 方法名 返回值 参数列表 访问修饰符
方法重写 子类 相同 相同 相同 比父类大
方法重载 本类 相同 无关 不同 无关

访问修饰符

类型 本类 本包 不同包子类 所有
private
默认的
protected
public

static关键字

static   静态的
修饰符:   属性、方法、代码块、内部类

    static修饰的属性:  静态变量
    1、静态变量直接通过类名.变量名调用,不需要创建类的对象
    2、静态变量也可以通过对象来调用,是因为它在堆内存中有一份拷贝
    3、静态变量在对象之间是共享

    在开发中,静态的变量用的很少。但是静态常量用的多
    public static final 类型  常量名 = 值:
    常量:
        常量不能改变
        常量必须要赋值

    static修饰的方法:  静态方法
    1、静态方法直接通过类名.方法名调用,不需要创建类的对象
    2、静态方法也可以通过对象来调用,是因为它在堆内存中有一份拷贝
    3、静态方法只能访问静态的变量和静态方法
    4、静态方法中不能使用this和super关键字    

    注意:非静态方法可以调用静态方法

    static修饰的代码块  静态代码块
    1、当类被加载的时候,静态代码块就会被执行
    2、静态代码块只会被加载一次
    3、静态代码块,优先于类的所有信息先执行

final关键字

final关键字
    修饰属性    常量
    1、常量一旦定义不能修改
    2、必须要赋值
    如:public static final String USERNAME= "root";        
    修饰方法    
    1、final修饰的方法不能被重写    
    修饰类
    1、final修饰的类不能被继承

注意: 静态方法不能被重写

多态

生活中的多态:同一个事物在不同环境下有不同的状态
人在不同的环境下身份不同
f1键在不同的软件下作用不同

程序中的多态:同一个对象在不同的环境下调用,功能不同

多态产生的条件

1、必须要有继承
2、父类的引用指向子类的对象(向上转型)
3、一定要有方法的重写

多态的特点

1、如果发生了多态,那么调用方法一定是子类重写的那个方法
2、如果发生了多态,那么父类引用无法调用子类自己的方法
    如果想要调用,那么就必须发生  向下转型  
    在发生向下转型之前,必须要发生向上转型。否则会有异常java.lang.ClassCastException(类转换异常)
3、如何避免程序出现类转换异常
    在转换之前,先判断是都是这个类型
    //判断对象是否是某一个类型
    //判断animal是否是Dog类型
    if(animal instanceof Dog) {
        Dog d = (Dog)animal;
        d.show();
    }

4、编译看左边,   运行看右边

抽象类

用abstract关键字修饰的类就称之为抽象类

抽象类的特点:   abstract关键字修饰
        1、有抽象方法的类必须是抽象类
        2、抽象类也可以没有抽象方法(没什么意义)
        3、抽象类不能被实例化

抽象类的作用   当爹的   一般都是用来作为父类被使用

抽象方法的特点:  abstract关键字修饰
        1、抽象方法不能有方法体(不同有{})
        2、抽象方法必须被子类重写,除非自己也是一个抽象类

接口

生活中的接口:接口定义了规范,是一种约束

public class 类名{
    成员变量
    成员方法
}
如何定义接口:
public interface 接口名{

}
接口中只能包含:
    静态常量    默认加上了  public static final修饰
    抽象方法    默认加上了  public abstract修饰

如何实现接口
public class 实现类 implements 接口名{
    //重写接口的抽象方法
}

如果使用接口  (利用多态)
MyInterface mi = new MyInterfaceImpl();
mi.show();

接口的特点:
    1、一个类可以实现多个接口  (类与接口之间是实现关系)
    2、一个接口可以继承多个接口(接口与接口之间是继承关系)
    3、一个类只能继承一个类

接口其实使用特殊的抽象类

接口和抽象类的区别

1、接口中必须都是抽象方法,抽象中类可以没有
2、接口中必须是静态常量,抽象类都可以
3、接口是被类实现(implements),抽象类是被继承(extends)
4、都不能被实例化

图书管理系统

  • 接口类
public interface UserInterface {
    //用户登录
    boolean login(User user);

    //用户注册
    void register(User user);

}

  • 接口实现类
public class UserInterfaceImpl implements UserInterface {
    //保存所有的用户信息
    User[] users = new User[0]; 
    @Override
    public boolean login(User user) {
        //遍历User数组中的所有用户对象
        for (int i = 0; i < users.length; i++) {
            User u = users[i];
            if(user.getUsername().equals(u.getUsername())   && user.getPassword().equals(u.getPassword())) {
                return true;
            }
        }
        return false;
    }

    @Override
    public void register(User user) {
        //定义长度比以前数组大1的新数组
        User[] users_1 = new User[users.length+1];        
        for (int i = 0; i < users.length; i++) {
            users_1[i] = users[i];
        }
        //将传进来的User存在数组的最后一个位置
        users_1[users_1.length-1] = user;        
        //将新数组赋给,成员变量的数组
        users = users_1;        
    }
}

  • User实体类
public class User {
    private String username;
    private String password;
    public User(String username, String password) {
        super();
        this.username = username;
        this.password = password;
    }
    public User() {
        super();
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
}
  • 菜单类
public class Menu {
    public static final int REG = 1;
    public static final int LOG = 2;
    public static final int EXIT = 3;
    //定义UserInterfaceImpl 对象,调用登录和注册的方法
    UserInterface userInterface = new UserInterfaceImpl();

    Scanner sc = new Scanner(System.in);    
    public void menu() {
        System.out.println("欢迎光临XXXX系统");
        System.out.println("1、注册");
        System.out.println("2、登录");
        System.out.println("3、退出");
        int num = sc.nextInt();
        switch (num) {
        case Menu.REG:

            System.out.println("请输入注册用户名");
            String username = sc.next();
            System.out.println("请输入注册密码");
            String password = sc.next();
            User user = new User(username, password);
            userInterface.register(user);

            menu();
            break;
        case Menu.LOG:
            System.out.println("欢迎登录");
            System.out.println("请输入用户名");
            String username1 = sc.next();
            System.out.println("请输入密码");
            String password1 = sc.next();
            User user1 = new User(username1, password1);
            boolean b = userInterface.login(user1);
            if(b == true) {
                System.out.println("进入图书管理系统~~~~");
            }else {
                System.out.println("登录失败,请检查你的账号和密码");
            }
            menu();

            break;
        case Menu.EXIT:
            System.out.println("欢迎下次使用~~~~");
            break;

        default:
            System.out.println("您的选择有误~请重新输入");
            menu();
            break;
        }
    }
}
  • 测试
public class Test {
    public static void main(String[] args) {
        Menu menu = new Menu();
        menu.menu();
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容