面向对象入门(类和对象)

面向对象入门(类和对象)

1.面向对象和面向编程思想
  • 面向过程编程思想: 强调的是过程, 必须清楚每一个步骤,然后按照步骤一步一步去实现

  • 面向对象编程思想:强调的是对象, 通过调用对象的行为来实现功能,而不是自己一步一步的去操作实现。类的概述

2.类与对象
  • 是用来描述一类具有共同属性和行为事物的统称。所以其实类在客观世界里是不存在的,是抽象的,只是用来描述数据信息的。

  • 类的组成:

    • 属性----共同拥有的
    • 行为----共同拥有的
  • 对象是类的一个实例(并不是你的女朋友哈),具体存在的,看得见摸得着的,并且具备该类事物的属性和行为

    • 对象的属性:对象的属性具有特定的值
    • 对象的行为:对象可以操作的行为
    • 类和对象的关系
  • 类和对象的关系

    • 类是对一类具有共同属性和行为的事物的统称,是抽象的

    • 对象是一类事物的具体实例,看得见,摸的着的,真实存在的实体,是具体的

    • 类是对象的抽象,对象是类的实体

3.成员变量默认值
  • 成员变量

    变量类型整数浮点型布尔型字符型引用类型
    默认值00.0false不可见字符 ‘\u0000’null
  • 局部变量: 定义在方法中的变量

    • 局部变量没有默认值
4.对象内存图
  1. jvm首先会调用main方法来执行程序
  2. java程序第一次使用某个类,就会把该类的字节码文件(.class)加载到方法区
  3. 凡是new就会在堆区开辟一块新的空间
  4. 方法一旦被调用就会被加载到栈区,开辟一块新的空间,来执行该方法
  5. 方法执行完毕后,就会弹栈(回收方法执行占用的栈空间)
  6. 对象是根据类来创建的,类有什么对象就有什么
  7. 堆区中的对象,如果没有变量指向,那么垃圾回收机制会在合适的时间进行回收该对象占用的空间

在这里插入图片描述

  • 多个对象内存

    • 多个对象在堆内存中,都有不同的内存划分,成员变量存储在各自对象的内存区域中,成员方法多个对象共用的一份

    • 凡是new就会重新在堆区开辟一块新空间

    • 对象和对象之间的关系是相互独立的

  • 多个变量指向相同对象

    • 当多个对象的引用指向同一个内存空间(变量所记录的地址值是一样的)
    • 只要有任何一个对象修改了内存中的数据,随后,无论使用哪一个对象进行数据获取,都是修改后的数据。
5.对象属性封装
  • 关键字private
    • 被private修饰的成员变量或者成员方法,只能在本类中访问
  • 为什么要对属性进行封装
    • 通过对象名直接访问成员变量的方式来对属性赋值,会存在数据安全隐患
  • set和get方法
    • 由于属性使用了private关键字修饰,在其他类中无法直接访问,所以得提供公共的访问方法,我们把这张方法叫做set和get方法,用public修饰
  • this关键字: this代表当前调用方法的引用,哪个对象调用this所在的方法,this就代表哪一个对象
    • this关键字其主要作用是区分同名的局部变量和成员变量
      • 方法的形参如果与成员变量同名,不带this修饰的变量指的是形参,而不是成员变量
      • 方法的形参没有与成员变量同名,不带this修饰的变量指的是成员变量
6.封装

概述:是面向对象编程语言对客观世界的模拟,客观世界里成员变量都是隐藏在对象内部的,外界是无法直接操作的

原则: 将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问

好处:

  • 通过方法来控制成员变量的操作,提高了代码的安全性
  • 把代码用方法进行封装,提高了代码的复用性
7.构造方法
  • 构造方法是一种特殊的方法,主要是完成对象的创建和对象数据的初始化

    • 构造方法的写法上,方法名与它所在的类名相同
    • 构造方法没有返回值,所以不需要返回值类型,甚至不需要void
    • 构造方法可以重载
  • 构造方法的创建

    • 如果没有定义构造方法,系统将给出一个默认的无参数构造方法
    • 如果定义了构造方法,系统将不再提供默认的构造方法
8.匿名对象:指"没有名字"的对象。
  • 特点: 匿名对象只能使用一次
9.继承
  • 定义: 在java中指的是“一个类”可以“继承自”“另一个类”。 "被继承的类"叫做: 父类/超类/基类,"继承其他类的类"叫做:子类。继承后,“子类”中就“拥有”了“父类”中所有的成员(成员变量、成员方法)。 “子类就不需要再定义了”。

  • 好处:通过继承可以将一些共性的属性,行为抽取到一个父类中,子类只需要继承即可

    1. 提高代码的复用性(减少代码冗余,相同代码重复利用)。
    2. 使类与类之间产生了关系。
  • 用法:

    通过 extends 关键字,可以声明一个子类继承另外一个父类,定义格式如下:

    class 父类 {
    	...
    }
    
    class 子类 extends 父类 {
    	...
    }
    

    需要注意:Java是单继承的,一个类只能继承一个直接父类,并且满足is-a的关系,例如:Dog is a Animal, Student is a Person

  • 访问规则:

    1. 父类的构造方法不能被子类继承
    2. 父类的“私有成员”可以被子类继承,但子类不能被直接访问。
    3. 当通过“子类”访问非私有成员时,先在子类中找,如果找到就使用子类的,找不到就继续去“父类”中找。
  • 特点:

    • 类的继承只能是单继承,不能多继承,但是可以多层继承
    • java中所有类都是直接或者间接继承Object,所有类都是Object类的子类
  • 继承体系内存图原理—父类空间优先于子类对象产生

    在每次创建子类对象时,先初始化父类空间,再创建其子类对象本身。目的在于子类对象中包含了其对应的父类空间,便可以包含其父类的成员,如果父类成员非private修饰,则子类可以随意使用父类成员。代码体现在子类的构造方法调用时,一定先调用父类的构造方法。
    在这里插入图片描述

10.方法重写
  • 子类中出现与父类一模一样的方法时(返回值类型,方法名和参数列表都相同),会出现覆盖效果,也称为重写或者复写。声明不变,重新实现
  • 注意:
    1. 方法重写是发生在子父类之间的关系。
    2. 子类方法重写父类方法,返回值类型、方法名和参数列表都要一模一样。
    3. 子类方法重写父类方法,必须要保证权限大于等于父类权限。
      • 访问权限从大到小: public protected (默认) private
11.this和super关键字
thissuper
访问范围本类的成员属性、成员方法、构造方法父类的成员属性、成员方法、构造方法
只能在本类的构造方法中使用this调用其他构造方法子类的构造方法默认会调用父类的空参构造方法
在本类的构造方法中使用this调用其他构造方法,必须放在该构造方法的第一行,否则会报错super访问父类的构造方法,可以用来初始化从父类继承过来的属性
两个构造方法不能使用this同时相互调用在子类的构造方法中,使用super调用父类的构造方法,必须放在子类构造方法的第一行
  • super访问成员变量和成员方法: 优先去父类中找,如果有就直接使用,如果没有就去爷爷类中找,如果有,就用,依次类推…
  • 子类的构造方法默认会调用父类的空参构造方法,如果父类中的没有空参构造方法,只定义了有参构造方法,会编译报错
  • 子类构造方法中使用super调用父类的构造方法,是为了在创建子类对象的时候,初始化从父类继承过来的属性
12.抽象类
  • 概述: 使用abstract关键字修饰的类就是抽象类
  • 特点: 这种类不能被创建对象,它就是用来做父类的,被子类继承的
格式:
修饰符 abstract class 类名{
    成员变量
    构造方法
    成员方法
    抽象方法                        
}
  • 抽象方法: 没有方法体,使用abstract修饰的方法就是抽象方法

    • 使用场景:如果父类中某个方法,所有子类都有不同的实现,那么就可以把该方法定义为抽象方法
    • 作用: 强制要求子类重写的
  • 注意事项:

    1. 抽象类不能被创建对象,就是用来做“父类”,被子类继承的。
    2. 抽象类不能被创建对象,但可以有“构造方法”——为成员变量初始化。
    3. 抽象类中可以没有抽象方法,但抽象方法必须定义在抽象类中
    4. 子类继承抽象类后,必须重写抽象类中所有的抽象方法,否则子类必须也是一个抽象类
13.模板设计模式
  • 针对某些情况,在父类中指定一个模板,然后根据具体情况,在子类中灵活的具体实现该模板
public abstract class Person{
    // 有方法体的方法: 通用模板
    public void sleep(){
        System.out.println("两眼一闭,就睡觉...");
    }
    
    // 没有方法体的方法(抽象方法):  填充模板(要子类重新实现的)
   public abstract void eat();
}
  • 抽象类体现的就是模板设计思想模板是将通用的东西在抽象类中具体的实现,而模板中不能决定的东西定义成抽象方法,让使用模板(继承抽象类的类)的类去重写抽象方法实现需求
模板模式的实现步骤
  • 定义抽象父类作为模板
  • 在父类中定义"模板方法"— 实现方法(通用模板)+抽象方法(填充模板)
  • 子类继承父类,重写抽象方法(填充父类的模板)
  • 测试类:
    • 创建子类对象,通过子类调用父类的“实现的方法”+ “子类重写后的方法”
14.final关键字

final: 不可改变。可以用于修饰类、方法和变量。

  • 类:被修饰的类,不能被继承。
  • 方法:被修饰的方法,不能被重写。
  • 变量:被修饰的变量,就只能赋值一次,不能被重新赋值。
修饰变量
局部变量——基本类型

​ 基本类型的局部变量,被final修饰后,只能赋值一次,不能再更改。

局部变量——引用类型

​ 引用类型的局部变量,被final修饰后,只能指向一个对象,地址不能再更改。但是不影响对象内部的成员变量值的修改。

public class FinalDemo {
    public static void main(String[] args) {
        // 引用类型
        final Student stu = new Student("张三",18);
        //stu = new Student("李四",19);// 编译报错
        stu.setAge(19);
    }
}
成员变量

​ 成员变量涉及到初始化的问题,初始化方式有两种,只能二选一:

  1. 显式初始化;

    public class FinalVariable {
        final int NUM1 = 10;
    }
    
  2. 构造方法初始化。

    public class FinalVariable {
        final int NUM2;
        public FinalVariable(int NUM2){
            this.NUM2 = NUM2;
        }
        public FinalVariable(){
            this.NUM2 = 10;
        }
    }	//所有的构造方法都必须为其初始化
    

被final修饰的常量名称,一般都有书写规范,所有字母都大写

15.static关键字

static是一个静态修饰符关键字,表示静态的意思,可以修饰成员变量成员方法以及代码块

  • static修饰成员变量

static 修饰成员变量时,该变量称为类变量。该类的每个对象都共享同一个类变量的值。任何对象都可以更改该类变量的值,但也可以在不创建该类的对象的情况下对类变量进行操作。
在这里插入图片描述

  • static修饰成员方法

被static修饰的方法会变成静态方法,也称为类方法,该静态方法可以使用类名直接调用。

  • 静态方法调用的注意事项:
    • 静态方法中不能出现this关键字
    • 静态方法中只能直接访问静态成员变量和静态成员方法
    • 静态方法中不能直接访问非静态成员变量和非静态成员方法
    • 非静态方法中可以直接访问一切成员变量和成员方法
16.接口

接口是Java语言中的一种引用类型,是方法的"集合",所以接口的内部主要就是定义方法,包含常量,抽象方法(JDK 7及以前),默认方法和静态方法(JDK 8),私有方法(jdk9)

引用数据类型:数组,类,接口。

  • 接口是java语言中的一种引用数据类型
  • 接口中的成员:
接口中的成员格式访问特点
常量(jdk7及其以前)public static final int NUM1 = 10;主要是供接口直接使用
抽象方法(jdk7及其以前)public abstract void method1();供实现类重写的
默认方法和静态方法(jdk8额外增加)public default void method3(){}
public static void method4(){}
默认方法:供实现类继承的
(实现类中可以直接调用,
实现类对象也可以直接调用)
静态方法: 只供接口直接调用,实现类继承不了
私有方法(jdk9额外增加)private static void method5()
private void method6()
只能在接口中直接调用,实现类继承不了
  • 定义接口使用interface关键字—接口编译后产生class文件
  • 接口不能创建对象,需要使用实现类实现接口(类似于继承),实现接口的类叫做实现类(子类)

实现接口:类与接口的关系为实现关系,即类实现接口,该类可以称为接口的实现类,也可以称为接口的子类。 实现的动作类似继承,格式相仿,只是关键字不同,实现使用 implements关键字。

  • 类可以实现一个接口,也可以同时实现多个接口。
    • 类实现接口后,必须重写接口中所有的抽象方法,否则该类必须是一个“抽象类”。
  • 类可以在“继承一个类”的同时,实现一个、多个接口;
  • 额外的功能—> 在接口中定义,让实现类实现
    • 如果可以确定的通用功能,使用默认方法
    • 如果不能确定的功能,使用抽象方法
  • 共性的功能—> 在父类中定义,让子类继承
    • 如果可以确定的通用功能,使用默认方法
    • 如果不能确定的功能,使用抽象方法
17.接口和接口的关系以及接口的冲突

接口和接口的关系:

​ 接口可以“继承”自另一个“接口”,而且可以“多继承”。

interface IA{}
interface IB{}
interface IC extends IA,IB{//是“继承”,而且可以“多继承”
}
冲突类型接口多实现时接口多继承接口
公有静态常量的冲突如果多个接口中有相同的常量,那么实现类就无法继承子接口无法继承父接口中冲突的常量
公有抽象方法的冲突实现类只需要重写一个子接口只会继承一个有冲突的抽象方法
公有默认方法的冲突实现类必须重写一次最终版本子接口中必须重写一次有冲突的默认方法,必须加default
公有静态方法的冲突静态方法是直接属于接口的,不能被继承,所以不存在冲突不冲突,因为静态方法是直接属于接口的,只能使用本接口直接访问
私有方法的冲突私有方法只能在本接口中直接使用,不存在冲突私有方法只能在接口中访问,也没有冲突
冲突类型实现类继承父类又实现接口时的冲突
公有静态常量的冲突子类无法继承有冲突的常量
公有抽象方法的冲突子类必须重写一次有冲突的抽象方法
公有默认方法的冲突优先访问父类的
公有静态方法只会访问父类的静态方法
私有方法的冲突不存在冲突
18.多态

定义

  • 多态: 是指同一行为,对于不同的对象具有多个不同表现形式。
  • 程序中多态: 是指同一方法,对于不同的对象具有不同的实现.

前提条件【重点】

  1. 继承或者实现【二选一】
  2. 父类引用指向子类对象\接口引用指向实现类对象【格式体现】
  3. 方法的重写【意义体现:不重写,无意义】

多态的体现: 父类的引用指向它的子类的对象:

父类类型 变量名 = new 子类对象;
变量名.方法名();

父类类型:指子类对象继承的父类类型,或者实现的父接口类型。

多态时访问成员的特点:

  • 成员变量:编译看父类,运行看父类(编译看左边,运行看左边)
    成员方法:
    非静态方法:编译看父类,运行看子类(编译看左边,运行看右边)
    静态方法: 编译看父类,运行看父类(编译看左边,运行看左边)
    结论:除了非静态方法是编译看父类,运行看子类,其余都是看父类

注意:多态的情况下是无法访问子类独有的方法

多态的形式:

  • 普通父类多态
  • 抽象父类多态
  • 父接口多态

多态的应用场景:

  1. 变量多态: 如果变量的类型为父类类型,该变量就可以接收该父类类型的对象或者其所有子类对象
  2. 形参多态:参数类型为父类类型,该参数就可以接收该父类类型的对象或者其所有子类对象
  3. 返回值多态:如果返回值类型为父类类型,那么就可以返回该父类类型的对象或者其所有子类对象

多态的好处和弊端:

  • 好处
    • 提高了代码的扩展性
  • 弊端
    • 多态的情况下,只能调用父类的共性内容,不能调用子类的特有内容。

引用类型转换:

  • 向上转型

    • 子类类型向父类类型向上转换的过程,这个过程是默认的。

       Aniaml anl = new Cat();  
      
  • 向下转型

    • 父类类型向子类类型向下转换的过程,这个过程是强制的。

       Aniaml anl = new Cat();  
       Cat c = (Cat)anl;//向下转型
      
  • 注意:
    1.向下转型的时候:右边父类类型的变量一定要指向要转型的子类类型的对象
    2.不管是向上转型还是向下转型,一定满足父子类关系或者实现关系

instanceof关键字

在引用类型转换的时候很容易出现类型转换异常,所以为了提高代码的严谨性,转型之前得先判断一下

if(变量名 instanceof 数据类型){
}
执行:
    判断前面变量指向的对象类型是否是后面的数据类型:
       如果前面变量指向的对象类型是属于后面的数据类型,那么就返回true
       如果前面变量指向的对象类型不是属于后面的数据类型,那么就返回false
19.内部类

将一个类A定义在另一个类B里面,里面的那个类A就称为内部类,B则称为外部类

  • 成员内部类 :定义在类中方法外的类。

    定义格式:

    class 外部类 {
        class 内部类{
    
        }
    }
    

    访问特点

    • 内部类可以直接访问外部类的成员,包括私有成员。
    • 外部类要访问内部类的成员,必须要建立内部类的对象。

    创建内部类对象格式:

    外部类名.内部类名 对象名 = new 外部类型().new 内部类型()
  • 匿名内部类: 是内部类的简化写法。它的本质是一个带具体实现的 父类或者父接口的 匿名的 子类对象

    格式:

    对于类:
    	概述:本质其实就是一个类的匿名子类的对象
        格式:
            new 类名(){
                实现抽象方法
            };
    对于接口:
    	概述:本质是一个接口的匿名实现类的对象
        格式:
            new 接口名(){
                实现抽象方法
            };
    使用场景:
    	如果方法的形参类型为抽象类或者接口类型,那么为了简化代码,可以直接传入该抽象类或者接口的匿名内部类
    
20.引用类型使用小结
  	  - 类名作为方法参数和返回值:可以直接传入该类的对象;返回该类的对象
      - 抽象类作为方法参数和返回值:只能传入该类的子类对象;返回该类的子类对象
      - 接口作为方法参数和返回值:只能传入该接口的实现类对象;返回该接口的实现类对象
          传递的都是地址值,返回的也是地址值
          
      - 类作为成员变量    : 赋该类的对象
      - 抽象类作为成员变量 ; 赋该类的子类对象
      - 接口作为成员变量   : 赋该接口的实现类对象
21.权限修饰符
publicprotected(空的)defaultprivate
同一类中
同一包中(子类与无关类)
不同包的子类
不同包中的无关类

可见,public具有最大权限。private则是最小权限。

编写代码时,如果没有特殊的考虑,建议这样使用权限:

  • 成员变量使用private ,隐藏细节。

  • 构造方法使用public ,方便创建对象。

  • 成员方法使用public ,方便调用方法。

22.代码块
  1. 构造代码块

    格式: {}
    位置: 类中,方法外
    执行: 每次在调用构造方法的时候,就会执行
    使用场景: 统计创建了多少个该类对象
    
  2. 静态代码块

    格式:static{}
    位置: 类中,方法外
    执行: 当类被加载的时候执行,并只执行一次
    使用场景: 例如加载驱动,这种只需要执行一次的代码就可以放在静态代码块中
    
  3. 局部代码块

    格式:{}
    位置: 方法中
    执行: 调用方法,执行到局部代码块的时候就执行
    使用场景: 节省内存空间,没有多大的意义
    
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值