Java面向对象

1.面向对象概述

我们学习编程语言最终目的是用程序去模拟现实生活中的事物,让事物与事物之间产生关系,然后模拟现实生活中的场景。
属性:就是对事物的描述      -------成员变量
行为:就是事物能够做什么事情 -------成员方法
    
成员变量:在类中方法外定义的变量都叫成员变量
语句定义格式:修饰符 数据类型 变量名;
​
成员方法:在类中定义
定义的格式与我们在学习时规范的定义语法是一样:
​
修饰符 返回值类型 方法名(参数类型1 参数名1,....){
    方法体;
    return  xxx;
}
注意:现在开始将static去掉!!!!
    
通过类去创建对象
//语句定义格式:
//类名 对象名 = new 类名();
//根据Person类创建一个人对象 Person p1=new Person();

 

class Student {
    //成员变量
    String name;
    //    int age;
    private int age;
 
 
    public int getAge() {
        return age;
    }
 
    public void setAge(int a) {
        if (a > 0 & a < 100) {
            age = a;
        } else {
            System.out.println("========================");
            System.out.println("=======年龄有误!!=======");
            System.out.println("========================");
        }
    }
 
    //成员方法
    public void study() {
        System.out.println("学习");
    }
 
    public void eat() {
        System.out.println("吃饭");
    }
}
 
public class StudentDemo {
    public static void main(String[] args) {
        //创建一个学生对象
        Student s1 = new Student();
        //给成员变量进行赋值
        s1.name = "reynolds";
        s1.setAge(18);
        System.out.println("姓名:" + s1.name + ", 年龄:" + s1.getAge());
 
    }
}

运行结果:

 

2.成员变量与局部变量的区别

在类中的位置不同
成员变量 类中方法外
局部变量 方法内或者方法声明上
    
在内存中的位置不同
成员变量 堆内存
局部变量 栈内存
​
生命周期不同
成员变量 随着对象的存在而存在,随着对象的消失而消失
局部变量 随着方法的调用而存在,随着方法的调用完毕而消失
    
初始化值不同   
成员变量 有默认的初始化值
局部变量 没有默认的初始化值,必须先定义,赋值,才能使用
匿名对象
匿名对象:就是没有名字的对象。是对象的一种简化表示形式
​
匿名对象的两种使用情况 
1.对象调用方法仅仅一次的时候 
2.作为实际参数传递
例:new Demo2().fun2(new Demo())

 

3.三大特征

3.1封装

3.1.1 封装概述

概念:是指隐藏对象的属性和实现细节,仅对外提供公共访问方式。
    
好处:隐藏实现细节,提供公共的访问方式 提高了代码的复用性 提高安全性。
    
封装原则:将不需要对外提供的内容都隐藏起来。把属性隐藏,提供公共方法对其访问。

3.1.2 private关键字

private关键字:是一个权限修饰符。可以修饰成员(成员变量和成员方法) 被private修饰的成员只在本类中才能访问。
private最常见的应用:把成员变量用private修饰提供对应的getXxx()/setXxx()方法 一个标准的案例的使用
//对于同一个文件夹下的类,类名不能重复
class Student2 {
    //成员变量
    private String name;
    private int age;
 
    public void setName(String s) {
        name = s;
    }
 
    public String getName() {
        return name;
    }
 
    public void setAge(int i) {
        age = i;
    }
 
    public int getAge() {
        return age;
    }
 
    //打印所有的成员变量值
    public void show() {
        System.out.println("姓名:" + name + ",年龄:" + age);
    }
}
 
public class StudentDemo2 {
    public static void main(String[] args) {
        //创建一个学生对象
        Student2 s1 = new Student2();
//        s1.name=
        s1.setName("reynolds");
        s1.setAge(18);
 
        String name = s1.getName();
        int age = s1.getAge();
        System.out.println("姓名:" + name + ",年龄:" + age);
        System.out.println("=========================================");
        s1.show();
 
    }
}

3.1.3 this关键字

this:代表所在类的对象引用 记住:方法被哪个对象调用,this就代表那个对象
什么时候使用this呢?     
1)局部变量隐藏成员变量
2)变量使用的就近原则:先在本方法中找,如果找不到再去成员变量中去找
class Student3{
    //成员变量
    private String name;
    private int age;
 
    public void setName(String name) { //String name = "刘璇"
        //变量使用遵循:就近原则
        this.name = name;
    }
 
    public String getName() {
        return name;
    }
 
    public void setAge(int age) {
        this.age = age;
    }
 
    public int getAge() {
        return age;
    }
 
    //打印所有的成员变量值
    public void show() {
        this.fun();  //表示本对象自己的方法,由于show()方法中也没有出现其他对象,this关键字也可以省略不写
        System.out.println("姓名:" + this.name + ",年龄:" + this.age);
    }
 
    public void fun(){
        System.out.println("今天天气不错!!");
    }
 
    private void fun2(){
        System.out.println("这是被private修饰fun2方法");
    }
 
    public void fun3(){
        fun2();
    }
}
 
public class StudentDemo3 {
    public static void main(String[] args) {
        //创建一个学生对象
        Student3 s1 = new Student3();
//        s1.name=
        s1.setName("reynolds");
        s1.setAge(18);
 
        String name = s1.getName();
        int age = s1.getAge();
        System.out.println("姓名:" + name + ",年龄:" + age);
        System.out.println("=========================================");
        s1.show();
//        s1.fun2();
        s1.fun3();
    }
}

3.1.4 构造方法

作用:给对象的数据进行初始化

语句定义格式  
1)构造方法的方法名与类名一致
2)没有返回值,连void都不能出现

构造方法注意事项
1)如果你不提供构造方法,系统会给出默认构造方法
2)如果你提供了构造方法,系统将不再提供,最好俩个有参无参都定义一下
3)构造方法也是可以重载的
Student() {
        System.out.println("=============你好=============");
    }
 
    Student(String name, int age) {
//        System.out.println("这是重载的方法"+s);
        this.name = name;
        this.age = age;
    }

使用alt+insert快捷键可以快速写构造方法和get,set方法

实例:

//以面向对象的思想,编写自定义类描述图书信息。设定属性包括:书名,作者,出版社名,价格;方法包括:信息介绍 show()
//要求:
//1)设置属性的私有访问权限,通过公有的 get,set 方法实现对属性的访问
//2)限定价格必须大于 10,如果无效进行提示
//3)限定作者,书名为只读属性
//4)设计构造方法实现对属性赋值
//5)信息介绍方法描述图书所有信息
//编写测试类,测试图书类的对象及相关方法(测试数据信息自定)
class Book{
    String bname;
    String author;
    String press;
    int price;
 
    public Book(String bname, String author, String press, int price) {
        this.bname = bname;
        this.author = author;
        this.press = press;
        if(price>10){
            this.price = price;
        }else{
            System.out.println("价格无效");
        }
    }
 
    public void setPrice(int price) {
        this.price = price;
    }
 
    public void setBname(String bname) {
        this.bname = bname;
    }
 
    public String getBname() {
        return bname;
    }
 
    public String getAuthor() {
        return author;
    }
 
    public String getPress() {
        return press;
    }
 
    public int getPrice() {
        return price;
    }
 
    public void show(){
        System.out.println("书名:"+bname+"\n作者:"+author+"\n出版社:"+press+"\n价格:"+price);
    }
 
}
public class Booktest {
    public static void main(String[] args) {
        Book b1=new Book("鹿鼎记","金庸","人民文学出版社",55);
        b1.show();
        System.out.println("-------------------------------------");
        Book b2=new Book("  ","古龙","人民文学出版社",55);
        b2.setBname("绝代双骄");
        b2.setPrice(100);
        b2.show();
 
    }
}

类的初始化过程

 

3.1.5 static关键字

static关键字:可以修饰成员变量和成员方法
java中将所有对象共享的成员,使用一个关键字进行修饰:static(静态的)

static关键字特点:
1)随着类的加载而加载
2)优先于对象存在
3)被类的所有对象共享 这也是我们判断是否使用静态关键字的条件
4)可以通过类名调用

static的使用
1、可以修饰成员变量,成员方法
2、被static修饰的成员,属于类成员(静态成员),可以使用类名.的方式直接调用,不需要创建对象
3、静态的成员方法只能访问静态的成员(包括成员变量,成员方法)
4、非静态的成员方法既可以访问静态的成员,也可以访问非静态的成员
5、static不能修饰构造方法
6、被static修饰的成员方法中不允许出现this关键字, 因为被static修饰成员是属于类本身是优先于对象而存在的,但是呢this关键字代表的是当前对象,所以两者意思上冲突了。

静态区的使用

 

解释main()方法的每一个单词

解释main方法的每一个单词
//public是公共的意思,指最大权限,因为main方法是由JVM所调用,所以权限一定要够大
//static,静态的意思,也就意味着不需要创建对象就可以被调用起来
//void:表示没有返回值的意思,因为main方法是由JVM所调用,给了返回值其实给的是JVM,没有意义
//main:方法的名字,定死的
//String[] args:方法的参数列表,是一个一维数组,元素类型是String类型的

3.1.6制作帮助文档

写法实例:

/**
 *
 * 这个类是专门对数组做操作的类,封装了比如打印数组、获取最大值等等方法,后续持续更新....
 * @author xiaohu
 * @version 1.0
 *
 */
public class ArrayTool {
 
    private ArrayTool(){
 
    }
 
    /**
     * 这个方法是获取int类型的一维数组中的最大值
     * @param arr arr是一维数组,元素是int类型的,参数的名字叫做arr
     * @return 返回值是int类型的元素,返回的是数组中的最大值
     */
    public static int getMaxNumber(int[] arr) {
        int maxNum = arr[0];
        for (int i = 1; i < arr.length; i++) {
            if (arr[i] > maxNum) {
                maxNum = arr[i];
            }
        }
 
        return maxNum;
    }
 
    /**
     * 这个方法用作以指定的输出格式打印int类型一维数组
     * 输出的格式为:[元素1,元素2,...]
     * @param arr arr是一维数组,元素是int类型的,参数的名字叫做arr
     */
    public static void printArray(int[] arr) {
        for (int i = 0; i < arr.length; i++) {
            if (i == 0) {
                System.out.print("[" + arr[i] + ",");
            } else if (i == arr.length - 1) {
                System.out.println(arr[i] + "]");
            } else {
                System.out.print(arr[i] + ",");
            }
        }
    }
}

在文件夹下运行 cmd

javadoc -d 目录 -author -version ArrayTool.java

例:javadoc -d ./wendang -author -version ./ArrayTool.java

生成帮助文档

3.1.7生成代码块

在Java中,使用{}括起来的代码被称为代码块,根据其位置和声明的不同,可以分为
1)局部代码块
2)构造代码块
3)静态代码块
4)同步代码块(多线程讲解)。

局部代码块:
在方法中出现;限定变量生命周期(作用域),及早释放,提高内存利用率
    
构造代码块
在类中没与任何的前缀或后缀,并使用"{}"括起来的代码片段
在类中方法外出现;多个构造方法中相同的代码存放到一起,每次调用构造都执行,并且在构造方法前执行
                  
静态代码块 
1)在类中方法外出现,加了static修饰
2)在类中方法外出现,并加上static修饰;用于给类进行初始化,在加载的时候就执行,并且值执行一次。和创建对象无关。

静态代码块(多个静态代码块之间是按照定义的顺序执行,自上而下)--->构造代码块(多个构造代码块之间是按照定义的顺序执行,自上而下)--->构造方法
public class CodeKuaiDemo {
    //在类中方法外出现,并加上static修饰
    static {
        System.out.println("这是静态代码块2。。。。");
    }
 
    CodeKuaiDemo(){
        System.out.println("这是我们自己提供的构造方法");
    }
 
    //构造代码块定义在类中方法外的,这个在创建对象的时候执行
    {
        int a = 10;
        System.out.println("hello World2构造代码块");
    }
 
    //在类中方法外出现,并加上static修饰
    static {
        System.out.println("这是静态代码块3。。。。");
    }
 
    //构造代码块定义在类中方法外的,这个在创建对象的时候执行
    {
        int a = 10;
        System.out.println("hello World3构造代码块");
    }
 
    //在类中方法外出现,并加上static修饰
    static {
        System.out.println("这是静态代码块1。。。。");
    }
 
 
 
    public static void main(String[] args) {
        //局部代码块,在方法中出现
//        {
//            int a = 10;
//            System.out.println("hello World");
//        }
//        System.out.println(a);
        CodeKuaiDemo codeKuaiDemo = new CodeKuaiDemo();
        System.out.println("=========================");
        CodeKuaiDemo codeKuaiDemo2 = new CodeKuaiDemo();
 
 
    }
}

3.2 继承

3.2.1 继承概述

把多个类中相同的部分提取到另一个类中,然后让多个类继承自这个类。
java使用extends关键实现继承
class 子类 extends 父类{}
(满足B is A )
class Fu{
    public void run(){
        System.out.println("跑");
    }
}
 
class Zi extends Fu{
 
}
 
public class ExtendsDemo {
    public static void main(String[] args) {
        Zi zi = new Zi();
        zi.run();
 
    }
}

继承的好处

1)提高了代码的复用性 多个类相同的成员可以放到同一个类中
2)提高了代码的维护性 如果功能的代码需要修改,修改一处即可
3)让类与类之间产生了关系,是多态的前提 其实这也是继承的一个弊端:类的耦合性很强
(耦合性:也叫块间联系,指软件系统结构中各模块间相互联系紧密程度的一种度量)

开发思想:低耦合,高内聚
(内聚(Cohesion),科学名词,是一个模块内部各成分之间相关联程度的度量。)

继承的特点

1)java中的继承不允许一个类同时继承多个类,只能单继承
2)java中的类支持多层继承,形成继承体系

继承的注意事项

1)子类只能继承父类中非私有的成员(成员变量或者成员方法)
2)继承关系中,子类无法继承父类的构造方法,父类构造方法最重要的意义是初始化子类对象之前,必须先对父类做初始化(要想有儿子,必须先有父亲)
3)不要为了部分的功能去使用继承
class Fu2{
    Fu2(){
        System.out.println("父类中的构造方法");
    }
 
}
 
class Zi2 extends Fu2{
    Zi2(){
        System.out.println("子类中的构造方法");
    }
}
 
public class ExtendsDemo2 {
    public static void main(String[] args) {
        Zi2 z=new Zi2();  //创建子类对象时,必须先对父类进行初始化
    }
}

输出结果:

 

3.2.2 super关键字

super的用法和this很像(this代表本类对应的引用)
super代表父类存储空间的标识(可以理解为父类引用)

用法(this和super均可如下使用)
1)访问成员变量                                   this.成员变量               super.成员变量
2)访问构造方法(子父类的构造方法问题讲)               this(…)                    super(…)
3)访问成员方法(子父类的成员方法问题讲)               this.成员方法()             super.成员方法() 
class Fu3{
    int a=10;
}
 
class Zi3 extends Fu3{
    int a=555;
    public void prin(int a){
        System.out.println(a); //采取就近原则
        System.out.println("this:"+this.a);  //获取本方法中的a变量
        System.out.println("super:"+super.a); //获取父方法中的a变量
    }
}
 
public class ExtendsDemo3 {
    public static void main(String[] args) {
        Zi3 zi3 = new Zi3();
        int a=666;
        zi3.prin(a);
    }
}

输出结果:

 

继承中构造方法的关系

子类中所有的构造方法默认都会访问父类中空参数的构造方法

1.子类的构造方法中第一句话上面默认会有一个super(),super()的意义就是调用父类的无参构造方法
2.如果父类中没有无参构造方法怎么办?
1)解决方案1:那么我们就在子类构造方法第一句话上面使用super关键字明着调用父类的构造方法,完成父类的初始化
2)解决方案2:利用子类中其他的构造方法,间接地调用父类中的其他构造方法,完成父类的初始化
\\解决方案1
 
class Fu4{
    Fu4(String s){
        System.out.println("对父类进行初始化");
    }
}
class Zi4 extends Fu4{
    Zi4(){
        super("  ");
    }
}
public class ExtendsDemo4 {
    public static void main(String[] args) {
        Zi4 zi4 = new Zi4();
    }
}

运行结果

 

//解决方法2
class Fu4{
    Fu4(String s){
        System.out.println("对父类进行初始化");
    }
}
class Zi4 extends Fu4{

    Zi4(String s){
        super(s);
    }

    Zi4(){
        this("   ");
        System.out.println("子类构造方法");
    }
}
public class ExtendsDemo4 {
    public static void main(String[] args) {
        Zi4 zi4 = new Zi4();
    }
}

运行结果:

 

3.2.3 方法的重写

继承中成员方法的关系

通过子类对象去访问一个方法
首先在子类中找
然后在父类中找
如果还是没有就报错。(不考虑父亲的父亲…)

方法重写概述

子类中出现了和父类中一模一样的方法声明,也被称为方法覆盖,方法复写。

当子类中的方法声明(返回值类型,方法名,参数列表)与父类中的方法声明一样,这样的现象叫做方法的重写,
一般是需要在子类重写的方法上加一个注解@Override,表示该方法是重写方法

使用特点

如果方法名不同,就调用对应的方法

如果方法名相同,最终使用的是子类自己的
面试题:方法的重载与方法的重写是什么区别?
1、重载是发生在同一个类中的,而重写是发生在继承关系中。
2、重载是方法名一样,方法参数列表不一样就叫重载,和返回值类型无关
3、重写要求方法返回值类型,方法名,参数列表都要与父类中的一致,只有权限修饰符和方法体的实现不一样 
class Fu5{
    public void test(){
        System.out.println("这是父类");
    }
}
 
class Zi5 extends Fu5{
    @Override
    public void test(){
        System.out.println("这是子类");
    }
}
 
public class ExtendsDemo5 {
    public static void main(String[] args) {
        Zi5 zi5 = new Zi5();
        zi5.test();
    }
}

运行结果:

 

继承中的注意事项

继承中重写的注意事项:
1、父类中私有方法不能被重写,私有的成员无法被子类继承,所以就更不要谈重写
2、子类重写父类方法时,访问权限不能更低  public  private,父类什么权限修饰符号,子类重写时同步
3、父类中的静态方法无法被子类进行重写

如果父类不想让子类重写非静态的方法,只想让子类使用Java们使用:
Java提供了一个关键字给我们使用:final(最终的,不可改变的)

3.2.4 final参数

final关键字的使用
1、final可以修饰类,成员变量,成员方法
2、被final所修饰的类,不能被继承
3、被final所修饰的成员变量,变量变成常量,值无法被改变
常量:
1)字面值常量
2)自定义常量:final所修饰的变量
在引用数据类型之前加上final关键字,指的是引用数据类型变量的地址值不能被改变
4、被final所修饰的成员方法,不能被重写

final修饰变量的初始化时机:在对象构造完毕前即可

class Demo2{
    final int a;
 
    //构造代码块,可以在构造方法之前执行
    {
        a = 20;
    }
    Demo2(){
        //..
    }
 
    public void fun1(){
        System.out.println(a);
    }
 
}
 
public class FinalDemo2 {
    public static void main(String[] args) {
        Demo2 demo2 = new Demo2();
        demo2.fun1();
    }
}

3.3 多态

3.3.1 多态概述

某一个事物,在不同时刻表现出来的不同状态。

举例:

猫可以是猫的类型。猫 m = new 猫();

同时猫也是动物的一种,也可以把猫称为动物。

动物 d = new 猫();

要想实现多态,必须满足三个条件:
1、必须要有继承关系
2、要有方法的重写,如果不重写语法上没问题,但是从意思上不合适
3、在创建对象的时候,要有父类的引用指向子类对象
class Person{
    String name;
    int age;

    public void study(){
        System.out.println("学习");
    }
}

class Student extends Person{
    @Override
    public void study() {
        System.out.println("学生学习大数据");
    }
}


public class DuoTaiDemo1 {
    public static void main(String[] args) {
        Person p = new Student(); //类与类之间的多态表现
    }
}

多态案例及成员访问特点

多态访问成员的特点:
1、访问成员方法的时候,编译看左,运行看右
2、访问成员变量的时候,编译看左,运行也看左
3、访问静态成员方法的时候,编译看左,运行也看左
 
class Futest{
    int a=1;
    public void fu(){
        System.out.println("这是父中的成员方法");
    }
 
    public static void fun(){
        System.out.println("这是父中的fun方法");
    }
 
}
 
class Zitest extends Futest{
    int a=999999;
    public void fu(){
        System.out.println("这是子中的成员方法");
    }
    public static void fun(){
        System.out.println("这是子中的fun方法");
    }
 
}
public class Duotaidemo2 {
    public static void main(String[] args) {
        Futest fu=new Zitest();
        System.out.println(fu.a);
        fu.fu();   //成员方法 编译看左边 运行看右边
        fu.fun();  //静态方法 编译看左边 运行看左边
    }
 
}

运行截图:

 

多态的好处与弊端

多态的好处:
提高了程序的维护性(由继承保证) 
提高了程序的扩展性(由多态保证)

多态的弊端:
1、不能访问子类特有功能
2、类和类之间的耦合性太强了
(今后的开发的原则:低耦合高内聚)
class Animal2{
    String name;
    int age;

    public void eat(){
        System.out.println("吃");
    }

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

class Cat2 extends Animal2{
    @Override
    public void eat() {
        System.out.println("🐱吃🐟");
    }

    @Override
    public void sleep() {
        System.out.println("🐱蜷着睡");
    }

}

class Dog2 extends Animal2{
    @Override
    public void eat() {
        System.out.println("🐕吃🥩");
    }

    @Override
    public void sleep() {
        System.out.println("🐕趴着睡");
    }
}

class Tiger extends Animal2{
    @Override
    public void eat() {
        System.out.println("🐅吃牛肉");
    }

    @Override
    public void sleep() {
        System.out.println("🐅趴着睡");
    }
}

class AnimalTool{
    private AnimalTool(){}

//    public static void useCat(Cat2 cat2){
//        cat2.eat();
//        cat2.sleep();
//    }
//
//    public static void useDog(Dog2 dog2){
//        dog2.eat();
//        dog2.sleep();
//    }

    public static void useAnimal(Animal2 animal2){ //Animal2 animal2 = new Tiger()
        animal2.eat();
        animal2.sleep();
    }
}

public class DuoTaiDemo2 {
    public static void main(String[] args) {
        //我想养一只猫
        Cat2 a1 = new Cat2();
//        a1.eat();
//        a1.sleep();
//        useCat(a1);
//        AnimalTool.useCat(a1);
        AnimalTool.useAnimal(a1); //new Cat2()

        //我还想养一只猫
        Cat2 a2 = new Cat2();
//        a2.eat();
//        a2.sleep();
//        useCat(a2);
//        AnimalTool.useCat(a2);
        AnimalTool.useAnimal(a2);
        //我还想养n只猫,又需要newn次,调用2n次方法,new对象我们避免不了n次,方法调用我可以进行封装
        //我不想养猫,我想养🐕
        Dog2 dog2 = new Dog2();
//        dog2.eat();
//        dog2.sleep();
        //随着我养的狗越来越多,这里就要new很多次
//        useDog(dog2);
//        AnimalTool.useDog(dog2);
        AnimalTool.useAnimal(dog2);
        //我不仅想要养狗或者猫了,我还想养🐅,🦁,熊猫等n种动物,咋办?
        //应该先写对应的动物类,继承自Animal类,然后再编写对应动物的方法,然后new对象调用。
        //随着动物的增多,类不可避免的增多,但是本类而言,方法也就变多了。
        //于是乎就在想,能不能将这些方法移动到一个类里面去,编写成动物的工具类
        //虽然我们使用工具类能够减轻本类的压力,但是呢我们之前说过,工具类不能够随意地改动
        //有什么方法既能够可以使用工具类调用方法,也可以做到不改变工具类里面的内容呢?(见现在没有被注释掉的工具类)
        Tiger tiger = new Tiger();
        AnimalTool.useAnimal(tiger);

    }

//    public static void useCat(Cat2 cat2){
//        cat2.eat();
//        cat2.sleep();
//    }
//
//    public static void useDog(Dog2 dog2){
//        dog2.eat();
//        dog2.sleep();
//    }
}

运行结果:

 

曹操曹植的故事

曹操和曹植是父子关系
class 曹操{
    public void jimo(){
        System.out.println("指挥打仗");
    }
}

class 曹植 extends 曹操{
    @Override
    public void jimo(){
        System.out.println("下棋");
    }

    public void xieshi(){
        System.out.println("写诗");
    }
}

某一天,曹操外出打仗了,这时候敌人攻打城池,但是曹植在家,这时候曹植开始穿上爹的衣服,粘上爹的胡子,开始装爹
曹操 c = new 曹植();
c.jimo();
//无法使用自己的特有本领,不然就露馅了
曹操回来了,曹植看到曹操回来后,脱下爹的衣服,撕掉胡子,做回自己
曹植 c2 = (曹植)c; //向下转型
c2.jimo();
c2.xieshi();

多态的转型

(多态的弊端:不能访问子类特有功能)

向下转型

class Fu{
    public void fun1(){
        System.out.println("这是父类中的fun1方法");
    }
}

class Zi extends Fu{
    @Override
    public void fun1() {
        System.out.println("这是子类中重写后的fun1方法");
    }

    public void show(){
        System.out.println("这是子类中特有的方法");
    }
}

public class DuoTaiDemo3 {
    public static void main(String[] args) {
        Fu fu = new Zi();
        fu.fun1();
//        fu.show();
        //向下转型
        Zi zi = (Zi)fu;
        zi.show();
    }
} 

运行结果:

 

向下转型有一个前提:转型的类要和父类的引用是一个继承关系

/*
    向下转型有一个前提:转型的类要和父类的引用是一个继承关系
 */

class Animal3{
    public void eat(){
        System.out.println("吃");
    }
}

class Cat3 extends Animal3{
    @Override
    public void eat() {
        System.out.println("猫吃🐟");
    }

    public void climb(){
        System.out.println("爬树");
    }
}

class Dog3 extends Animal3{
    @Override
    public void eat() {
        System.out.println("🐕吃🥩");
    }

    public void lookDoor(){
        System.out.println("看门");
    }
}

public class DuoTaiDemo4 {
    public static void main(String[] args) {
        //使用多态创建一个猫的对象
        Animal3 animal = new Cat3();
        animal.eat();
//        animal.climb(); //多态访问成员方法编译看左,运行看右
        //向下转型
//        Cat3 c = (Cat3) animal;
//        c.climb();
//        c.eat();
        Dog3 dog3 = (Dog3) animal;  //ClassCastException类型转换异常
        dog3.lookDoor();
    }
}

ClassCastException:类型转换异常(多态向下转型)

错误代码

//错误代码
/* ClassCastException:类型转换异常
     一般在多态的向下转型中容易出现
 */
class Animal{
	public void eat() {
	System.out.println("eat");	
	}
}
class Cat extends Animal{
	public void eat() {
	System.out.println("猫吃鱼");		
	}
	public void play() {
		System.out.println("猫玩毛线");
	}
}
class Dog extends Animal{
    public void eat() {
    System.out.println("狗吃肉");		
	}
    public void method() {
    	System.out.println("狗玩球");		
    }
}
public class FinalTestDemo1 {
  public static void main(String[] args) {
	
    Animal a = new Dog();
	Dog d = (Dog)a;
	d.eat();
	d.method();
	a = new Cat();
	Cat c = (Cat)a;
	c.eat();
	c.play();
	//报错:ClassCastException:类型转换异常
	//是因为上一级堆中存的是Cat的地址,而dog不能访问cat类,必须要重新创建对象
	Dog dd = (Dog)a;
   }
}
正确代码
//正确代码
class Animal{
	public void eat() {
	System.out.println("eat");	
	}
}
class Cat extends Animal{
	public void eat() {
	System.out.println("猫吃鱼");		
	}
	public void play() {
		System.out.println("猫玩毛线");
	}
}
class Dog extends Animal{
    public void eat() {
    System.out.println("狗吃肉");		
	}
    public void method() {
    	System.out.println("狗玩球");		
    }
}
public class FinalTestDemo1 {
  public static void main(String[] args) {
      Animal a = new Cat();
	  Cat c = (Cat)a;
	  c.eat();
	  c.play();
	  a = new Dog();
	  Dog d = (Dog)a;
	  d.eat();
	  d.method();
	 
	  Dog dd = (Dog)a;
	  dd.eat();
	  dd.method();
   }
}

运行结果:

 

 

具体案例

 

4.抽象类

4.1 抽象类概述

回想前面我们的猫狗案例,提取出了一个动物类。并且我们在前面也创建过了动物对象,其实这是不对的。
为什么呢?
因为:我说动物,你知道我说的是什么动物吗?只有看到了具体的动物,你才知道,这是什么动物。 所以说,动物本身并不是一个具体的事物,而是一个抽象的事物。只有真正的猫,狗才是具体的动物。同理,我们也可以推想,不同的动物吃的东西应该是不一样的,所以,我们不应该在动物类中给出具体体现,而是应该给出一个声明即可。
    
大家去想一下,我们之前定义的人类,动物类,这些在现实生活中并没有具体的体现。
所以这些在现实生活中表示抽象的概念的时候,不应该将其定义成一个能够创建对象的类,而更应该是一个抽象意义上的类。
java提供了一个关键字给我们使用,表示抽象的意思:abstract
它能够修饰类,修饰成员方法
在Java中,一个没有方法体的方法应该定义为抽象方法,而类中如果有抽象方法,该类必须定义为抽象类。

4.2 定义抽象类

如何定义一个抽象类?java针对于这个机制提供了一个关键字:abstract

abstract关键字的用法:
1、修饰类,类变成了抽象类
2、修饰方法,方法变成了抽象方法,没有具体的实现,没有方法体,连大括号都没有
    
使用注意事项:
1、一个类加上了abstract关键字就变成了抽象类,抽象类不能被实例化(不能创建对象)
既然不能创建对象,有构造方法意义是什么?这里构造方法是为了初始化父类的提供作用的
2、抽象类中可以存在非抽象的方法,也可以存在抽象的方法,但是抽象的方法没有方法体
3、如果一个类中存在抽象方法,这个类必须是抽象类
4、如果一个具体的类继承自抽象类,必须重写抽象类中的所有抽象方法
5、抽象类也可以继承抽象类,可以不去重写父抽象类中的抽象方法
6、抽象类中既可以存在变量也可以存在常量

//尝试使用抽象类改写之前的猫狗案例
//将动物类定义成抽象类,加上abstract关键字
abstract class Animal{
    //对于吃这个方法而言,也不应该有具体的实现,
    //所以需要将这个方法也变成抽象方法,抽象方法没有方法体,连大括号都没有
    public abstract void eat();
}

abstract class Demo extends Animal{

}

class Dog extends Animal{
    @Override
    public void eat(){
        System.out.println("🐕吃🥩");
    }
}

public class AbstractDemo1 {
    public static void main(String[] args) {
        //创建对象
        Dog dog = new Dog();
        dog.eat();
        System.out.println("===============================");
        //Animal animal = new Animal();  //从现实生活出发考虑一个抽象意义的东西没法实例化

    }
}

运行结果: 

 
abstract class Animal4{
    int a = 10;
    final int b = 20;

    public abstract void eat();
    public abstract void sleep();

}

abstract class Demo extends Animal4{

}

class Cat4 extends Animal4{

    @Override
    public void eat() {
        System.out.println("猫吃🐟");
    }

    @Override
    public void sleep() {
        System.out.println("猫蜷着睡");
    }
}


public class AbstractDemo1 {
    public static void main(String[] args) {
//        Animal4 animal4 = new Animal4();
        Animal4 a = new Cat4();  //抽象多态
        a.eat();
        a.sleep();
    }
}
运行结果:
/*
    一个类如果没有抽象方法,可不可以定义为抽象类?
        可以
    如果可以,有什么意义?
        像我们生活中有很多的概念是无法用具体的类或者方法去描述的,但我们可以通过语言去归纳总结一个范围
        就可以将这个概念定义一个抽象类
 */

abstract class Demo2{
//    private abstract void fun1(); //java: 非法的修饰符组合: abstract和private

//    public static abstract void fun1(); //java: 非法的修饰符组合: abstract和static

//    public final abstract void fun1();  //java: 非法的修饰符组合: abstract和final
}

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

    }
}

 

4.3 抽象类中成员的特点

成员变量:可以是变量也可以是常量
构造方法:可以存在构造方法,但是不能实例化,写构造方法的意义是为了今后初始化子类之前先初始化本类
成员方法:可以有抽象方法 限定子类必须完成某些动作,也可以有非抽象方法 提高代码服用性,也可以存在含有具体实现的方法
    
实现方法的快捷键:alt+enter
abstract class Demo2{
    int a;
    final int b =10;

    Demo2(){

    }

    public void fun1(){

    }

    public abstract void fun2();
}

class Demo2Zi extends Demo2{
    @Override
    public void fun2(){

    }
}

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

    }
}

4.4 具体案例

/*
        老师案例
        具体事物:二十二期老师,二十三期老师
        共性:姓名,年龄,讲课。

 */



abstract class Teacher{
    private String name;
    private int age;

    public Teacher() {
    }

    public Teacher(String name, int age) {
        this.name = name;
        this.age = age;
    }

    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 abstract void teach();
}

class TwentyTwoTeacher extends Teacher{
    public TwentyTwoTeacher() {
    }

    public TwentyTwoTeacher(String name, int age) {
        super(name, age);
    }

    @Override
    public void teach() {
        System.out.println("22期老师讲解java");
    }


}

class TwentyThreeTeacher extends Teacher{
    public TwentyThreeTeacher() {
    }

    public TwentyThreeTeacher(String name, int age) {
        super(name, age);
    }

    @Override
    public void teach() {
        System.out.println("23期老师讲解mysql");
    }
}
public class AbstractDemo3 {
    public static void main(String[] args) {
        //创建一个22期老师
        TwentyTwoTeacher tt1 =new TwentyTwoTeacher("小虎",18);
        tt1.teach();
        System.out.println("========================================");
        Teacher t1 = new TwentyTwoTeacher("小虎",17);
        //由于父类是抽象类,所以这种多态又有一个新的叫法:抽象多态
        t1.teach();
    }
}
package com.shujia.ztt.day08;
/*
        假如我们在开发一个系统时需要对员工类进行设计,员工包含3个属性:姓名、工号以及工资。
        经理也是员工,除了含有员工的属性外,另为还有一个奖金属性。
        请使用继承的思想设计出员工类和经理类。要求类中提供必要的方法进行属性访问。
 */


abstract class Staff{
    private String name;
    private String id;
    private int salary;

    public Staff() {
    }

    public Staff(String name, String id, int salary) {
        this.name = name;
        this.id = id;
        this.salary = salary;
    }

    public String getName() {
        return name;
    }

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

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public int getSalary() {
        return salary;
    }

    public void setSalary(int salary) {
        this.salary = salary;
    }

    public abstract void work();
}

class GeneralWorkers extends Staff{
    public GeneralWorkers() {
    }

    public GeneralWorkers(String name, String id, int salary) {
        super(name, id, salary);
    }

    @Override
    public void work() {
        System.out.println("写sql,写java,写python,写shell,写JS,写HTML");
    }
}

//PM project Manager/Product Manager
class Manager extends Staff{
    private int comm;

    public Manager(int comm) {
        this.comm = comm;
    }

    public Manager(String name, String id, int salary, int comm) {
        super(name, id, salary);
        this.comm = comm;
    }

    @Override
    public void work() {
        System.out.println("做PPT,开会");
    }
}

public class AbstractDemo4 {
    public static void main(String[] args) {
        Staff s1 = new GeneralWorkers("胡龙庆", "ali001", 20000);
        s1.work();

        System.out.println("=============================");
        Staff s2 = new Manager("刘璇", "tx002", 30000, 100000);
        s2.work();
    }
}

4.5 其他

1、一个类如果没有抽象方法,可不可以定义为抽象类?如果可以,有什么意义?
   可以。
   有意义,像我们生活中有很多的概念是无法用具体的类或者方法去描述的,但我们可以通过语言去归纳总结一个范围
   表示现实生活中一个抽象概念的汇总,尽管类中没有其他内容,但是从逻辑上是有意义的。

2、abstract不能和哪些关键字共存
private	冲突
final	冲突
static	冲突,静态的没法重写
abstract class Demo3{
    private int a;

    //因为抽象方法本身的意义就是为了今后具体的类继承抽象类去重写的
    //加上了private关键字之后,子类没法重写,所以冲突
//    private abstract void fun1();

//    final abstract void fun2();

//    static abstract void fun2();

}

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

    }
} 

5.接口

5.1 接口概述

继续回到我们的猫狗案例,我们想想狗一般就是看门,猫一般就是作为宠物了,对不。
但是,现在有很多的驯养员或者是驯兽师,可以训练出:猫钻火圈,狗跳高,狗做计算等。
而这些额外的动作,并不是所有猫或者狗一开始就具备的,这应该属于经过特殊的培训训练出来的,对不。
所以,这些额外的动作定义到动物类中就不合适,也不适合直接定义到猫或者狗中,因为只有部分猫狗具备这些功能。
    
所以,为了体现事物功能的扩展性,Java中就提供了接口来定义这些额外功能,
并不给出具体实现,将来哪些猫狗需要被培训,只需要这部分猫狗把这些额外功能实现即可。
接口:表示一个类的扩展功能,将来哪些类需要实现该功能,实现该接口即可。
就是某一个事物本身的功能有限,想要进行扩展功能的时候可以使用接口。
//需求:马戏团的猫会跳高
abstract class Animal5{
    public abstract void eat();
}

class Cat5 extends Animal5{

    @Override
    public void eat() {
        System.out.println("🐱吃🐟");
    }
}

interface Jumping{
    public abstract void jump();
}

class JumpCat extends Animal5 implements Jumping{

    @Override
    public void eat() {
        System.out.println("🐱吃🐟");
    }


    @Override
    public void jump() {
        System.out.println("猫跳高");
    }
}


public class InterfaceDemo1 {
}

5.2 定义接口

格式:interface 接口名 {}
  
可以将接口看作是一个特殊的类

注意:
接口名的命名方式与类名的命名方式是一样
就将接口看作是一个特殊的类,因为接口编译的时候也会被编译成一个class文件
    
注意事项:
1、接口中只允许存在抽象方法,并且系统会默认在每一个方法前加上public abstract
2、一个类要想实现接口,使用implements关键字进行实现
3、接口中只能存在常量,不允许变量存在,默认在变量的前面加上public static final
4、抽象类可以实现接口,但是可以不去实现抽象方法,也可以实现
5、一个具体的类实现接口,必须要实现接口中所有抽象方法
6、一个类可以继承一个类的同时实现多个接口,也可以直接实现多个接口
7、接口没有构造方法,它不能创建对象(不能实例化)
    
接口的使用注意事项:
1、接口中只允许存在抽象方法,默认会在方法前加上public abstract
2、当具体的类实现接口的时候,必须要实现接口中所有抽象方法
3、接口不能进行实例,没有构造方法
 4、接口中只允许存在常量,不允许变量存在,默认会在变量前加上public static final
5、接口和接口之间存在继承关系,可以进行多继承
        6、类和接口之间是实现关系,一个类可以同时实现多个接口(举例:抽烟敲代码学生既可以敲代码,也会抽烟)
/*
    接口:就是某一个事物本身的功能有限,想要进行扩展功能的时候可以使用接口。当然今后接口的具体使用,是由后面具体的类实现
    抽象类动物:
        抽象方法:abstract eat()

    狗 extends 动物:
        eat(){🐕吃🥩}

    某些狗的特有功能:骑自行车,但是呢又不能直接定义在狗的类中,如果直接定义在类中,就意味着所有的狗都会骑自行车
    所以java提供了一个机制给我们使用,当我们需要写扩展功能的时候,就可以定义一个接口
    这里就可以将骑自行车定义成一个接口
    将来哪些狗需要骑自行车,只需要实现这个接口即可

    1、定义一个接口,接口中有骑自行车方法
    2、抽象父类:动物类Animal
    3、普通的狗类:Dog
    4、经过训练的狗类:SpecialDog


 */

//定义接口的语句格式 interface 接口名
//注意:接口名的命名方式与类名的命名方式是一样
//就将接口看作是一个特殊的类,因为接口编译的时候也会被编译成一个class文件
interface Bicycle{
    int a=10;

//    Bicycle(){
//
//    }

    void bike();
}

interface RopeSkipping{
    void skip();
}

//abstract class Demo4 implements Bicycle{
//    @Override
//    public void bike() {
//
//    }
//}

//class A implements Bicycle{
//
//
//}

class Cat implements Bicycle,RopeSkipping{

    @Override
    public void bike() {

    }

    @Override
    public void skip() {

    }
}


abstract class Animal2{
    public abstract void eat();
}

class Dog2 extends Animal2{

    @Override
    public void eat() {
        System.out.println("🐕吃🥩");
    }
}

class SpecialDog extends Animal2 implements Bicycle{
    public void fun1(){
//        a =100;
        System.out.println(a);
    }

    @Override
    public void bike() {
        System.out.println("经过训练的狗狗会骑自行车");
    }

    @Override
    public void eat() {
        System.out.println("🐕吃🥩");
    }
}


public class InterfaceDemo1 {
    public static void main(String[] args) {
        //创建经过训练的狗
        SpecialDog specialDog = new SpecialDog();
        specialDog.eat();
        specialDog.bike();
        specialDog.fun1();
        System.out.println("================================");
        //创建一个普通的狗
        Dog2 dog2 = new Dog2();
        dog2.eat();
//        dog2.bike();

//        System.out.println(Bicycle.a);
//        Bicycle bicycle = new Bicycle();

        Cat b1 = new Cat();  //接口多态
        b1.bike();
        b1.skip();


    }
}
interface Inter1{}

interface Inter2{}

interface Inter3 extends Inter1,Inter2{}

interface Code{
//    public void Coding(){
//        System.out.println("敲代码");
//    }
    int a = 10;

    public abstract void Coding();
}

interface Smoke{
    void smoking();
}

//抽象类可以实现接口
abstract class Demo3 implements Smoke{

}



class Person6{

}

//一个类可以在继承一个类的同时实现多个接口
class CodeStudent extends Person6 implements Code,Smoke{

    @Override
    public void Coding() {
//        a = 11; //java: 无法为最终变量a分配值
        System.out.println(a);
        System.out.println("敲代码");
    }

    @Override
    public void smoking() {
        System.out.println("会抽烟");
    }
}

public class InterfaceDemo2 {
    public static void main(String[] args) {
//        Code code = new Code();
//        CodeStudent codeStudent = new CodeStudent();
//        codeStudent.Coding();
//        System.out.println(Code.a);
//        CodeStudent codeStudent = new CodeStudent();
//        codeStudent.smoking();
//        codeStudent.Coding();

        Smoke s = new CodeStudent();  //接口多态
        s.smoking();
//        s.Codeing();
    }
}

5.3 接口特点

接口用关键字interface表示 
格式:interface 接口名 {}

类实现接口用implements表示
格式:class 类名 implements 接口名 {}

接口不能实例化
那么,接口如何实例化呢?
按照多态的方式,由具体的子类实例化。其实这也是多态的一种,接口多态。

接口的子类
要么是抽象类
要么重写接口中的所有抽象方法

5.4 接口成员特点

成员变量
只能是常量
默认修饰符 public static final
    
构造方法
没有,因为接口主要是扩展功能的,而没有具体存在
    
成员方法
只能是抽象方法
默认修饰符 public abstract

5.5 类与类,类与接口以及接口与接口的关系

类与类
继承关系,只能单继承,但是可以多层继承

类与接口
实现关系,可以单实现,也可以多实现。还可以在继承一个类的同时实现多个接口

接口与接口
继承关系,可以单继承,也可以多继承

5.6 抽象类和接口的区别

成员区别
抽象类 变量,常量;有抽象方法;抽象方法,非抽象方法
接口 常量;抽象方法
    
关系区别
类与类 继承,单继承
类与接口 实现,单实现,多实现
接口与接口 继承,单继承,多继承
    
设计理念区别
抽象类 被继承体现的是:”is a”的关系。共性功能
接口 被实现体现的是:”like a”的关系。扩展功能

5.7 具体案例

package com.shujia.ztt.day08;

/*
    猫狗案例,加入跳高的额外功能

    猫:
        姓名,年龄
        吃
    狗:
        姓名,年龄
        吃
    会跳高的猫:
        姓名,年龄
        吃
        跳高
    会跳高的狗:
        姓名,年龄
        吃
        跳高
    ----------------------
    动物类(抽象类):
        姓名,年龄
        吃(抽象方法)

    跳高(接口):
        跳高(抽象方法)

    猫 extends 动物类:
        重写吃方法

    狗 extends 动物类:
        重写吃方法

    会跳高的猫 extends 动物类 implements 跳高:
        重写吃方法
        重写跳高方法
    会跳高的狗 extends 动物类 implements 跳高:
         重写吃方法
         重写跳高方法


 */

interface Jumping{
    void jump();
}

abstract class Animal6{
    String name;
    int age;

    public abstract void eat();
}

class Dog6 extends Animal6{
    @Override
    public void eat(){
        System.out.println("狗吃肉");
    }
}

class Cat6 extends Animal6{
    @Override
    public void eat(){
        System.out.println("猫吃鱼");
    }
}

class JumpDog extends Animal6 implements Jumping{
    @Override
    public void jump(){
        System.out.println("狗会跳高");
    }

    @Override
    public void eat(){
        System.out.println("狗吃肉");
    }

}

public class InterfaceDemo2 {
    public static void main(String[] args) {
        //创建一只普通的狗
        Dog6 dog6= new Dog6();
        dog6.eat();
        //dog6.jump();
        System.out.println("================================");
        //创建一只会跳高的狗
        JumpDog jumpDog = new JumpDog();
        jumpDog.eat();
        jumpDog.jump();

    }
}

教练和运动员案例(学生分析然后讲解) ​ 乒乓球运动员和篮球运动员。 ​ 乒乓球教练和篮球教练。 ​ 为了出国交流,跟乒乓球相关的人员都需要学习英语。 ​ 请用所学知识: ​ 分析,这个案例中有哪些抽象类,哪些接口,哪些具体类。

//分析:抽象类:Person类 Coach类 Player类
//     具体类:RattleCoach BasketballCoach RattlePlayer BasketballPlayer


import com.sun.org.apache.xerces.internal.dom.PSVIAttrNSImpl;

//定义接口
interface LearnEnglish{
    void lenglish();
}

//定义抽象类
abstract class Person{
    String name;
    int age;
    String duty;  //职业

}

abstract class Coach extends Person{
    public abstract void teach();
}

abstract class Player extends Person{
    public abstract void can();

}

//定义具体的类
class RattleCoach extends Coach implements LearnEnglish{
    @Override
    public void teach(){
        System.out.println("我会教乒乓球");
    }

    @Override
    public void lenglish(){
        System.out.println("我要学英语");
    }


}

class BasketballCoach extends Coach{
    @Override
    public void teach(){
        System.out.println("我会教篮球");
    }

}

class RattlePlayer extends Player implements LearnEnglish{
    @Override
    public void can(){
        System.out.println("我会打乒乓球");
    }

    @Override
    public void lenglish(){
        System.out.println("我要学英语");
    }

}

class BasketballPlayer extends Player{
    @Override
    public void can(){
        System.out.println("我会打篮球");
    }

}

public class InterfaceDemo3 {
    public static void main(String[] args) {
        //创建不用学英语的对象
        BasketballCoach bc1 = new BasketballCoach();
        bc1.teach();
        System.out.println("==========================");
        BasketballPlayer bp1 = new BasketballPlayer();
        bp1.can();
        System.out.println("==========================");
        //创建学英语的对象
        RattleCoach rc1 = new RattleCoach();
        rc1.teach();
        rc1.lenglish();
        System.out.println("==========================");
        RattlePlayer rp1 = new RattlePlayer();
        rp1.can();
        rp1.lenglish();

    }
}

6.形式参数和返回值问题

形式参数
基本类型
引用类型:
数组:当数组作为方法的形式参数的时候,传入的是数组的地址值
类:当看到类作为方法参数的数据类型的时候,将来调用时需要传入的时该类或者该类的子类对象
接口:当看到接口作为方法的形参数据类型的时候,将来调用时,需要传入的是实现该接口具体的类的对象
抽象类:当看到一个抽象类作为方法的形式参数的时候,将来调用时需要传入的是该抽象类的具体的子类对象

返回值类型
基本类型
引用类型
数组:当数组作为方法的形式参数的时候,传入的是数组的地址值
类:当你看到一个类作为方法的返回值类型的时候,方法中需要返回该类或者该类的子类对象
接口:当你看一个接口作为方法的返回值类型的时候,方法中需要返回实现该接口的具体的类的对象
抽象类:当你看到一个抽象类作为方法的返回值类型的时候,方法中需要返回继承该抽象类的具体子类对象
 

7.包的划分

com.shujia.wyh   域名.企业或者项目名.模块

xxx的管理系统

管理员用户
普通用户

1、按照功能进行划分
    增加
       管理员的增加
       普通用户的增加
    删除
       管理员的删除
       普通用户的删除
    更新
       管理员的更新
       普通用户的更新
    查询
       管理员的查询
       普通用户的查询

2、按照成员模块划分
    管理员模块
        管理员的增加
        管理员的删除
        管理员的更新
        管理员的查询
    用户模块
        普通用户的增加
        普通用户的删除
        普通用户的更新
        普通用户的查询

举例:JavaEE web开发中通常的包设计
com.xxx.xxx
    controller
    entity(pojo)
    service
    dao
    utils

7.1 不同包下类的划分

定义两个类:Demo,Test。
Demo
求和方法(sum)
Test
测试方法(main)

代码实现

public class Demo {
    public void sum(int a,int b){
        System.out.println(a+b);
    }
}
package com.shujia.ztt.day07.review.bao2;
import com.shujia.ztt.day07.review.bao1.Demo;
import java.util.Scanner;
public class Test {
    public static void main(String[] args) {
        Demo demo = new Demo();
        demo.sum(10,20);
    }
}

7.2 权限修饰符

Java权限修饰符是用来控制类、方法、变量等元素在程序中的访问权限的关键字。Java中的权限修饰符有public、protected、default(即不写任何修饰符)、private四种。它们的作用分别是:
- public表示公共的,任何类都可以访问;
- protected表示保护的,同一包中的类和子类可以访问;
- default表示默认的,同一包中的类可以访问;
- private表示私有的,只有本类中的方法可以访问。
    在使用权限修饰符时,需要根据实际情况进行选择,以保证程序的安全性和可读性。

8.内部类

内部类:顾名思义,定义在类中的类,称之为内部类

根据在类中定义的位置不同,分为两种内部类:
1、成员内部类:定义在类中方法外的类
2、局部内部类:定义在方法内的类

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值