编程语言
首页 > 编程语言> > Java第一阶段面向对象

Java第一阶段面向对象

作者:互联网

第一天

一、什么是类?什么是对象?

1.现实生活中是由很多很多对象组成的,基于对象抽出类

2.对象:软件中真实存在的单个个体/东西

类:类别/类型,代表一类个体

3.类是对象的模子,对象是类的具体的实例

4.类可以包含:

        对象的属性/特征--------成员变量

        对象的行为/动作--------方法

5.一个类可以创建多个对象

二、创建类,创建对象,访问成员

三、方法重载(overload)-----更加方便用户访问

        发生在同一类中,方法名相同,参数列表不同

四、项目:潜水艇

潜艇游戏需求:
1.所参与的角色:
    窗口:宽(?),高(479)
    1)战舰Battleship
        属性:宽(66),高(26),x坐标(270),y坐标(124),移动速度(20),命数(5)
        行为:移动move()
    2)侦察潜艇ObserveSubmarine
        属性:宽(63),高(19),x坐标(-width),y坐标(150到(窗口高-潜艇高)之内的随机数),移动速度(1~3)
        行为:移动move()
    3)鱼雷潜艇TorpedoSubmarine
        属性:宽(64),高(20),x坐标(-width),y坐标(150到(窗口高-潜艇高)之内的随机数),移动速度(1~3)
        行为:移动move()
    4)水雷潜艇MineSubmarine
        属性:宽(63),高(19),x坐标(-width),y坐标(150到(窗口高-潜艇高)之内的随机数),移动速度(1~3)
        行为:移动move()
    5)水雷Mine
        属性:宽(11),高(11),x坐标(写活),y坐标(写活),移动速度(1)
        行为:移动move()
    6)深水炸弹Bomb
        属性:宽(9),高(12),x坐标(写活),y坐标(写活),移动速度(2)
        行为:
2.角色间的关系:
    1_1)战舰发射深水炸弹;
    1_2)深水炸弹可以打潜艇(侦察潜艇、鱼雷潜艇、水雷潜艇),若打中:
        ① 潜艇消失,深水炸弹消失;
        ② 得东西:
            打掉侦察潜艇,玩家得10分;
            打掉鱼雷潜艇,玩家得40分;
            打掉水雷潜艇,战舰得1条命.
    2_1)水雷潜艇可以发射水雷;
    2_2)水雷可以击打战舰,若打中:
        ① 水雷消失;
        ② 战舰减一条命(命数为0时游戏结束).


第二天 

一、构造方法(构造函数、构造器、构建器)-----------复用给成员变量赋初值代码(作用)

--方法名与类名相同,且没有返回值类型(void都没有)

--在创建(new)对象时自动被调用

--若不写构造方法,编译器默认提供一个无参构造方法,若写构造方法,编译器不会自动生成构造方法

--构造方法可以重载

二、this:指代当前对象,哪个对象调用方法它指的就是哪个对象

1. 只能用在方法中,方法中访问成员变量之前默认有个this.

2.this的用法:

1)this.成员变量名---------------访问成员变量

成员变量与局部变量同名时,若想访问成员变量则this不能省略

2)this.方法名----------调用方法(了解)

3)this()-------------------调用构造方法(了解)

三、null和NullPointerException

null表示空,没有指向任何对象,若引用的值为null,则该引用不能进行任何点操作了,否则会发生NullPointerException空指针异常

四、引用类型数组(以潜艇项目为例)

Bomb[] bs = new Bomb[3];
bs[0] = new Bomb(100,200); //1)给元素赋值需要去new个对象
bs[1] = new Bomb(200,300);
bs[2] = new Bomb(220,330);
//2)若想访问对象的数据,需要通过数组元素去打点
bs[0].x = 111; //给第1个炸弹的x修改为111  
System.out.println(bs[1].width); //输出第2个炸弹的宽
bs[2].move(); //第3个炸弹移动

五、补充

1.内存管理:由JVM管理

1)堆内存:new的对象(还有实例变量)

2)栈内存: 局部变量(包括方法的参数)



第三天

一. 引用类型数组:

二. 继承:

   - 作用:代码复用

   - 通过extends来实现继承

   - 超类/父类:共有的属性和行为

     派生类/子类:特有的属性和行为

   - 派生类既能访问自己的,也能访问超类的,但超类不能访问派生类的

   - 一个超类可以有多个派生类

     一个派生类只能有一个超类-----------单一继承

   - 具有传递性

   - java规定:构造派生类之前必须先构造超类

     - 派生类的构造方法中若没有调用超类的构造方法,则默认super()调用超类的无参构造方法
     - 派生类的构造方法中若自己调用了超类的构造方法,则不再默认提供

      super()调用超类构造方法,必须位于派生类构造方法的第一行

三. super:指代当前对象的超类对象

   super的用法:

   - super.成员变量名----------------------访问超类的成员变量(了解)
   - super.方法名()---------------------------调用超类的方法----------明天讲
   - super()-------------------------------------调用超类的构造方法

四. 向上造型:---------------------代码复用

   - 超类型的引用指向了派生类的对象
   - 能点出来什么,看引用的类型-----------这是规定,记住就OK了

补充:

1. 继承意味着代码虽然我没有写,但也属于我,只是没有写在一起而已
2. 泛化:将共有的抽出来的过程,泛化是设计层面的概念,从代码实现层面来说咱们就是继承,泛化就是继承
3. 继承要符合is a(是一个)的关系



第四天

一、方法的重写(override/overriding):重新写、覆盖

1.发生在父子类中,方法名相同,参数列表相同

2.重写方法被调用时,看对象的类型

二、重写与重载的区别(面试重点):

1.重写(override)-------父子类中,方法名相同,参数列表相同

多态中,重写的方法看对象

一般用于在派生类中修改超类的方法

2.重载(overload)------同类中,方法名相同,参数列表不同

是完全不同的方法,只是方法名相同而已

三、package和import

 - package:声明包

     - 作用:避免类的命名冲突
     - 同包中的类不能同名,不同包中的类可以同名
     - 类的全称:包名.类名,包名常常有层次结构
     - 建议:包名所有字母都小写

     > 说明:package声明包必须位于第一行

   - import:导入类

     - 同包中的类可以直接访问,不同包的类不能直接访问,若想访问:
       - 先import导入类,再访问类----------建议
       - 类的全称-----------------------------------太繁琐,不建议

     > 说明:import导入类必须位于声明包的下一行

四、访问控制修饰符

封装的意义:隐藏一些东西,暴露一些东西,来保护数据的安全

public:公开的,所有类

protected:受保护的 当前类,派生类,同包类

默认的:本类,同包类

private:私有的 本类

1. 类的访问权限只能是public或默认的
2. 类中成员的访问权限如上四种都可以

五、static:静态的

 静态变量:
     - 由static修饰
     - 属于类,存储在方法区中,只有一份
     - 常常通过类名点来访问
     - 何时用:所有对象所共享的数据(图片、音频、视频等)
   - 静态方法:
     - 由static修饰
     - 属于类,存储在方法区中,只有一份
     - 常常通过类名点来访问
     - 静态方法没有隐式this传递,所以不能直接访问实例成员
     - 何时用:方法的操作与对象无关
   - 静态块:
     - 由static修饰
     - 属于类,在类被加载期间自动执行,一个类只被加载一次,所以静态块也只执行一次
     - 何时用:初始化/加载静态资源(图片、音频、视频等)

补充:

1. 成员变量分两种:

   - 实例变量:没有static修饰,属于对象的,存储在堆中,

     ​                    有几个对象就有几份,通过引用打点来访问

   - 静态变量:有static修饰,属于类的,存储在方法区中,

     ​                    只有一份,通过类名打点来访问

2. 内存管理:由JVM来管理的

   - 堆:new出来的对象(包括实例变量)
   - 栈:局部变量(包括方法的参数)
   - 方法区:.class字节码文件(包括静态变量、所有方法)

3. 在构造方法中给实例变量做初始化

   在静态块中给静态变量做初始化

4.两同两小一大

1)两同:方法名相同,参数列表相同

2)两小:

派生类方法的返回值类型必须小于或等于超类方法的

        ----是void或基本数据类型时,必须相等

        ----引用类型时,小于或等于

派生类方法抛出的异常必须小于或等于超类方法的

3)一大:

派生类方法的访问权限必须大于或等于超类方法的



第五天

一、final

1.修饰变量:变量不能被改变

2.修饰方法:方法不能被重写

3.修饰类:类不能被继承

二、static final常量

1.必须声明同时初始化

2.通过类名点来访问,不能被改变

3.建议:常量名所有字母都大写,多个单词用_分隔

4.编译器在编译时会将常量直接替换为具体的值,效率高

5.何时用:数据永远不变,并且经常使用

三、抽象方法:

1.由abstract修饰

2.只有方法的定义,没有具体的实现(连{}都没有)

四、抽象类:

1.由abstract修饰

2.包含抽象方法的类必须是抽象类

3.抽象类不能被实例化(new对象)

4.抽象类是需要被继承的,派生类:

1)重写所有抽象方法-------变不完整为完整

2)也声明为抽象类----------一般不这么做

五.抽象类的意义:

1)封装共有的属性和行为----代码复用

2)为所有派生类提供统一的类型------向上造型----代码复用

3)可以包含抽象方法,为所有派生类提供统一的入口(能点出来)

           ----派生类的行为不同,但入口是一致的,同时相当于定义了一个标准

补充:

  1. 设计规则:

    • 将所有派生类所共有的属性和行为,抽到超类中-------------抽共性

    • 派生类的行为都一样,则设计为普通方法

      派生类的行为不一样,则设计为抽象方法

    • 将部分派生类共有的属性和行为,抽到接口中

    • 接口是对继承的单根性的扩展-----------实现多继承

            ---符合既是也是原则时,应使用接口
  2. 抽象方法/抽象类的疑问:

    • 抽象方法的存在意义是什么?

      保证当发生向上造型时,通过超类型的引用能点出来那个方法
    • 既然意义只在于能点出来,那为什么不设计为普通方法?

      若设计为普通方法,则派生类可以重写也可以不重写,而设计为抽象方法,可以强制派生类必须重写------做了个标准,强制必须重写


第六天

一、成员内部类:应用率低,了解

class Aoo{ //外部类
    class Boo{ //内部类
    }
}

--类中套类,外面的称为外部类,里面的称为内部类
--内部类通常只服务于外部类,对外不具备可见性

--内部类对象只能在外部类创建

--内部类可以直接访问外部类的成员(包括私有的),在内部类中有个隐式的引用指向了创建它的外部类对象---外部类名.this

二、匿名内部类:应用率高

--若想创建一个类(派生类)的对象,并且对象只创建一个,此时该类不必命名,称为匿名内部类

--匿名内部类中不能修改外面变量的值,因为在此处默认变量为final的

public class AnonInnerClassDemo{
    public static void main(String[] args){
        //1)创建了Aoo的一个派生类,但没有名字
        //2)为该派生类创建了一个对象,名为o1
        //3)大括号中的为派生类的类体
        Aoo o1 = new Aoo(){
        };

        //由于大括号为派生类的类体,所以抽象方法要重写
        Boo o2 = new Boo{
            void show(){
                System.out.println( "showshow" );
            }
        };
        o2.show();
    }
}


abstract class Boo{
    abstract void show();
}

abstract class Aoo{
}

补充:

1.隐式对象:

--this:当前对象

--super:当前对象的超类对象

--外部类名.this:当前对象的外部类对象

2.必须记住的,API中会用的:

--外部类名.this-------------指代当前对象的外部类对象

--匿名内部类不能修改外面变量的值,因为在此处默认变量为final的

3.面试题:

--问:内部类独立生成.class字节码文件吗?

--答:是

4.做功能的套路:

1)先写行为/方法:

--若为某对象所特有的行为,就将方法设计在特定的类中

--若为所有对象所共有的行为,就将方法设计在超类中

2)窗口调用:

--若为定时发生的,就在定时器中调用

--若为事件触发的,就在侦听器中调用

5.调错方式

--打桩:System.out.println(数据);



第七天

一、接口

1.语法:

1)是一种引用数据类型

2)由interface来定义(没有class关键字)

3)只能包含常量和抽象方法(默认权限是public且默认常量和抽象方法,可以省略修饰符)

4)接口不能被实例化

5)接口是需要被实现,实现类:必须重写所有抽象方法

--重写接口的方法时,访问权限必须设计为public的

6)一个类可以实现多个接口

--若又继承又实现时,应先继承后实现

7)接口可以继承接口(extends)

2.何时用:

接口的意义:

--封装部分派生类共有的属性和行为,实现多继承

--制定了一个标准,一种规范

3.用它的好处---------------第八天内容

补充:

1.类和类-----------------继承extends

   接口和接口-----------继承extends

   类和接口--------------实现implements

2.接口可以向上造型



第八天

一、多态

1.表现:

1.同一个对象被造型为不同的类型时,有不同的功能

--对象的多态:

我(学生、儿子、哥哥)、你(老师、母亲)、水(气态、液态、固态)......-----------所有对象都是多态的

2.同一个类型的引用指向不同的对象时,有不同的实现

--行为的多态:move(),getImage(),getScore().....------------所有抽象方法都是多态的

2.向上造型/自动类型转换------代码复用

--超类的引用指向派生类的对象

--能点出来什么看引用 

--能造型成为的数据类型有:超类+所实现的接口

3.强制类型转换,成功的条件只有如下两种:

--引用所指向的对象,就是该类型

--引用所指向的对象,实现了该接口或继承了该类

PS:强转时若不符合如上条件,则发生ClassCastException类型转换异常

1.建议:在强转之前先通过instanceof来判断引用的对象是否是该类型

2.何时需要强转?

        想访问的属性/行为在超类中没有,必须强转;强转之前先instanceof判断



第九天

一、内存管理:由JVM管理

1.堆:

--存储new出来的对象(包括实例变量)

--垃圾:没有任何引用所指向的对象

垃圾回收器(GC)不定时到内存中清扫垃圾,回收的过程中透明的(看不到的),不一定一发现垃圾就立刻回收,通过调用System.gc()建议虚拟机尽快调度GC来回收

--实例变量的生命周期:

        创建对象时存储在堆中,对象被回收时一并被回收

--内存泄漏:不再使用的对象没有被及时的回收,严重的泄漏会导致系统的崩溃

        建议:不再使用对象应及时把引用设置为null

2.栈:

--存储正在调用的方法中的局部变量(包括方法的参数)

--调用方法时,会为该方法在栈中分配一块对应的栈帧,栈帧中存储局部变量(包括方法的参数),方法调用结束时,栈帧被自动清除,局部变量一并被清除

--局部变量的生命周期:

        调用方法时存储在栈中,方法调用结束时,栈帧被自动清除,局部变量一并被清除

3.方法区:

--存储.class字节码文件(包括静态变量,所有方法)

--方法只有一份,

二、面向对象三大特征总结

1.封装:

        1)类:封装对象的属性和行为

        2)方法:封装的是具体的业务逻辑实现

        3)访问控制修饰符:封装的是具体的访问权限

2.继承:

        1)作用:代码复用

        2)超类:所有派生类所共有的属性和行为

           接口:部分派生类所共有的属性和行为

           派生/实现类:派生类所特有的属性和行为

        3)单一继承、多接口实现,具有传递性

3.多态:

        1)行为多态:所有抽象方法都是多态的(通过重写来表现)

           对象多态:所有的对象都是多态的(通过向上造型来表现)

        2)重写、向上造型、强制类型转换、instanceof判断

补充:

1.实例变量和局部变量的区别:

        实例变量:

                --写在类中,方法外

                --创建对象时存储在堆中,对象被回收时一并被回收

                --有默认值

        局部变量:

                --写在方法中

                --调用方法时存储在栈中,方法调用结束时,栈帧被自动清除,局部变量一并被清除

                --没有默认值

2.面试题:

问:java是值传递,还是引用传递?

答:java中只有值传递,基本数据类型传递的是具体的数,引用数据类型传递的是地址值

3.文档注释

文档注释是功能性的注释,只在三个地方使用,分别是类上,方法上,常量上.

        1)在类上使用时,用来说明当前类的设计目的和整体功能介绍

/**

作者必须写,建议用英文名
@author XKB
see表示参考的哪个类
@see java.lang.String
*/

        2)在常量上使用时,用来说明该常量用于哪个方法

/**
* sayGoodbye方法中使用的问候语
*/
public static final String INFO = "再见!";

        3)在方法上使用时,用来说明参数和返回值(输入/**再按回车会自动生成注解@)

/**
* 为指定的用户添加问候语
* @param name 指定用户的名字
* @return 含有问候语的字符串
*/
public String sayGoodbye( String name ){
    return INFO + name;
}

4.get/set

标签:Java,构造方法,--,面向对象,对象,超类,派生类,方法,第一阶段
来源: https://blog.csdn.net/CabbageTomato/article/details/122415851