Java面向对象

面向对象

面向对象概述

面向对象思想:
在程序中使用对象来映射现实中的事物,使用对象的关系来描述事物之间的联系。

  • 面向过程就是分析出解决问题所需要的步骤,然后用函数把这些 步骤实现,使用的时候来调用函数。
  • 面向对象则是把构成问题的事物按照一定规则划分为多个独立的对象,通过调用对象的方法来解决问题。

面向对象的特点: 封装、继承、多态。

  • 封装:将对象的属性和行为封装起来,不需要让外界知道具体实现细节。
  • 类的封装是指将对象的状态信息隐藏在对象内部,不允许外部程序直接访问对象的内部信息,而是通过该类所提供的方法来实现对内部的操作访问。
    具体实现过程是,再定义一个类时,将类中的属性私有化,即使用private来修饰,只能在类中被访问,如果外界想要访问私有属性,需要提供一些使用public修饰的共有方法,如getXxx()、setXxx()。
  • 继承:主要描述的是类与类之间的关系,通过继承可以在无需重新编写原有类的情况下,对原有类的功能进行扩展。增强了代码的复用性。
  • 多态:多态指的是在一个类中定义的属性和功能被其它类继承后,当把子类对象直接赋值给父类引用变量时,相同引用类型的变量调用同一个方法所呈现出来的多种不同行为特征。
    多态的一种使用形式是“父类 引用 = new 子类()”。
    向上转型和运行时动态绑定是多态的两种实现机制。
Java中的类与对象

类与对象的关系
面向对象的编程思想力图在程序中对事物的描述与该事物在现实中的形态保持一致,提出了类和对象的概念。

  • 类是具有相同属性和行为的一系列实例化集合,是自定义数据类型。
  • 类是对某一类事物的抽象描述,而对象用于表示现实中该类事物的个体。
  • 对象是类的具象化,并且一个类可以对应多个对象。
类的定义
  • 类的定义格式:
    [修饰符] class 类名 [extends 父类名] [implements 接口名]{ //类体,包括类的成员变量和成员方法 }
    class前面的修饰符可以是public,也可以不写(默认);
    被public修饰的类必须与源文件名相同。
    在这里插入图片描述

class之后是定义的类名,类名首字母大写,并且其命名要符合标识符的命名规则。extends是继承父类 implements是实现哪个接口。

  • 声明成员变量:
    [修饰符] 数据类型 变量名[=值]
    将没有初始化的变量称为声明变量,初始化的变量称为定义变量。
  • 声明成员方法:
    成员方法也被称为方法,它主要用于描述对象的行为。
[修饰符] [返回值类型] 方法名 ([参数类型 参数名1,参数类型 参数名2,……])
{
//方法体
return 返回值;  //当方法的返回类型为void时,return及其返回值可以忽略
}

定义在类中的变量被称为成员变量,定义在方法中的变量被称为局部变量,
如果在某一个方法中定义的局部变量与成员变量同名,这种情况是允许的,此时方法中通过变量名访问到的是局部变量,而非成员变量。

对象的创建与使用
1.类名 对象名称 = new 类名();
2.new 类名().对象成员     

第二中方法在创建实例对象的同时访问对象的成员,创建后只能访问其中的某一成员,而不能访问多个对象成员,同时没有引用对象的存在,在完成访问后会变成垃圾对象,所以一般使用对象引用。

Person p = new Person();

Person p 是声明了一个Person类型的变量p。中间的等号用于将Person对象
在内存中的地址赋值给变量p,p就持有了对象的引用。
Java将内存分为两种,即栈内存和堆内存。其中栈内存用于存放基本类型的变量和对象的引用变量(对象在内存中的地址),堆内存用于存放由new创建的对象和数组。

  • 对象的引用
对象引用.对象成员
public class Example{
public static void main (String[] args){
Person p1=new Person();
Person p2=new Person();
p1.age=18;                //为age属性赋值
p2.speak();                  //调用对象的方法
}
}

对象被实例化后,在程序中可以通过对象的引用变量来访问该对象的成员。
当没有任何变量引用这个对象时,它将变成垃圾对象,不能再被使用。

方法的重载和递归
  • 方法的重载: 一个程序中定义多个名称相同,但是参数的类型或个数不同的方法。方法的重载与返回值类型无关,只需要满足两个条件,一是方法名相同,二是参数个数或参数类型不同。
  • 方法的递归:在一个方法的内部调用自身的过程。递归必须要有结束条件,不然会陷入无限递归的状态。
构造方法

构造方法(也称为构造器)是类的一个特殊成员,它会在类实例化对象时被自动调用。可以在实例化对象同时为对象属性赋值。

[修饰符] 方法名 ([参数列表]){
//方法体
}

构造方法须同时满足三个条件:
①方法名与类名相同
②在方法名的前面没有返回值类型的声明。
③在方法中不能使用return语句返回一个值,但是可以单独写return语句来作为方法的结束。
通过有参的构造方法可以实现对属性的赋值。
在Java的每个类中至少有一个构造方法,如果没有显式地定义构造方法系统会自动生成一个没有参数,方法体中没有任何代码的默认构造方法,一旦类定义了构造方法系统不再提供默认的构造方法。
为了方便实例化对象,构造方法通常会使用public来修饰。

  • 构造方法的重载
    一个类中可以定义多个构造方法,只要每个构造方法的参数类型或参数个数不同即可。
this关键字

Java中提供了一个关键字this来指代当前对象,用于在方法中访问对象的其他成员。

  • 通过this关键字调用成员变量,解决与局部变量名称。
    this.变量名访问成员变量
  • 通过this关键字调用成员方法
    this.成员方法 this可省略
  • 通过this调用构造方法
    在程序中不能像调用其他方法一样去调用构造方法,但可以在一个构造方法中使用this([参数1,参数2,…])的形式来调用其他的构造方法。
    使用this调用类的构造方法时,需要注意:
    ①只能在构造方法中使用this调用其他构造方法,不能再成员方法中使用。
    ②在构造方法中,使用this调用构造方法的语句必须时该方法的第一条执行语句,且只能出现一次。
    ③不能在一个类的两个构造方法中使用this互相调用。
static关键字
  • 静态变量:某些特定的数据在内存中只有一份,而且能够被一个类的所有实例对象所共享。

静态变量的调用:

类名.变量名

static关键字只能用于修饰成员变量,不能用于修饰局部变量。

  • 静态方法:不创建对象的情况下调用方法。
    使用:在类中定义的方法前加上static

静态方法的访问:

类名.方法
实例对象名.方法

在一个静态方法中,只能访问static修饰的成员,原因在于没有被static修饰的成员需要先创建对象才能访问,而静态方法在被调用时可以不创建任何对象。

  • 静态代码块
static{}

当类被加载时,静态代码块会执行,由于类只加载一次,因此静态代码块也只执行一次。在程序中,通常会使用静态代码块来对类的成员变量进行初始化。在执行静态代码块后调用main()方法。静态代码块只在编译时执行一次。

类的继承
  • 继承的概念
    在程序中,继承描述的是事物之间的所属关系,通过继承可以使多种事物之间形成一种关联体系。
    在Java中,类的继承是指在一个现有类的基础上去构建一个新的类,构建出来的新类被称作子类,现有类被称作父类或基类,子类会自动拥有父类所有可继承的属性和方法。子类在继承父类的时候,会自动拥有父类所有公共的成员。
[修饰符] class 子类名 extends 父类名 {
//程序核心代码
}

需要注意的问题:
(1)在Java中,类只能单继承,不允许多重继承,也就是说一个类只能有一个直接父类。
(2)多个类可以继承同一个父类。
(3)在Java中,多层继承是可以的,即一个类的父类可以再去继承另外的父类。
(4)在Java中,子类和父类是一种相对概念,也就是说一个类是某个类父类的同时,也可以是另一个类的子类。

  • 重写父类方法
    在继承关系中,子类会自动继承父类中公共的方法,但子类需要对继承的方法进行一些修改,即对父类的方法进行重写。子类中重写的方法需要和父类被重写的方法具有相同的方法名、参数列表以及返回类型。子类重写父类方法时,不能使用比父类中被重写的方法更严重的访问权限。如父类中的方法访问的是public,子类重写父类该方法的访问权限就不能是private。
    私有方法和私有成员变量可以被继承但不能被访问,私有成员变量可以通过getset方法访问,私有方法可以通过public修饰的方法中使用来访问。
  • super关键字
    当子类重写父类的方法后,子类对象将无法直接访问父类被重写的方法,需要使用super关键字来访问父类的成员。
super.成员变量
super.成员方法([参数1,参数2,...])

使用super关键字调用父类的构造方法

super([参数,参数2...])

需要注意,通过super调用父类构造方法的代码必须位于子类构造方法的第一行,并且只能出现一次,否则程序在编译期间就会报错。
子类在实例化时默认调用父类无参的构造方法,在定义一个类时,如果没有特殊需求,当定义了有参构造方法后,尽量在类中再显式地定义一个无参构造方法,这样可以避免该类被继承时出现错误。

  • Object类
    Java中提供了一个Object类,它是所有类的父类,即每个类都直接或间接继承自该类,因此Object类通常被称为超类、基类或跟类。当定义了一个类时,如果没有使用extends关键字为这个类显示的指定父类,那么该类会默认继承自Object类。
final关键字

final关键字可用于修饰类、变量和方法,被final修饰有以下特性:
①final修饰的类不能被继承。
②final修饰的方法不能被子类重写。
③final修饰的变量(成员变量和局部变量)是常量,只能赋值一次。
Java中被final修饰的变量被称为常量,它只能被赋值一次,赋值后不能被改变,final关键字修饰成员变量时,Java虚拟机不会对其进行初始化,被final修饰的成员变量,必须在声明的同时进行初始化,否则编译报错,final修饰的局部变量可以先声明,再赋值。

抽象类和接口
  • 抽象类
    当定义了一个类时,需要定义一些方法来描述该类的行为特征,有时这些方法的的实现方式无法确定,需要有方法但不需要提供方法的实现,可以使用抽象方法。
    抽象方法必须使用abstract关键字来修饰,并且在定义方法时不需要实现方法体。当一个类中包含了抽象方法,类就变成了抽象类需要用abstract来修饰。
[修饰符] abstract class 类名{
[修饰符] abstract 方法返回值类型 方法名 ([参数列表]);
}

注意:包含抽象方法的类必须要定义为抽象类,但抽象类中可以不包含任何抽象方法。抽象类不可以被实例化,因为抽象类中可能含有抽象方法,抽象方法没有方法体,不可以被调用。如果想要调用抽象方法,需要创建一个子类来实现抽象类中的抽象方法。
抽象类需要通过子类来实例化,而 final 修饰的类不能含有子类,因此抽象类不能被 final 修饰。

  • 接口
    接口是一个特殊的抽象类,它不包含普通方法,其内部的所有方法都是抽象方法。
    在JDK8中,对接口进行了重新定义,接口中除了抽象方法外,还可以有默认方法和静态方法(也叫类方法),默认方法使用default修饰,静态方法使用static修饰,并且这两种方法都允许有方法体。
    接口的定义:
[修饰符] interface 接口名 [extends 父接口1,父接口2,...]{
[public] [static] [final] 常量类型 常量名=常量值;
[public] [abstract] 方法返回值类型 方法名 ([参数列表]);
[public] default 方法返回值类型 方法名 ([参数列表]){
//默认方法的方法体
}
[public] static 方法返回值类型 方法名 ([参数列表]){
//静态方法的方法体
}
}

定义一个接口时,可以同时继承多个父接口,解决了类的单继承限制,在接口内部可以定义多个常量和抽象方法,定义常量时必须进行初始化赋值,定义默认方法和静态方法时,可以有方法体。
在接口定义时,public static final,public abstract可以省略系统会默认进行添加,定义default默认方法和static静态方法时,可以省略public修饰符。静态方法可以通过接口名.方法名来调用,抽象方法和默认方法只能通过接口实现类的实例对象来调用。因此需要定义一个接口的实现类,这个类通过implements关键字实现当前接口,并实现接口中所有抽象方法。

[修饰符] class 类名 [extends 父类名] [implements 接口1,接口2,...]{
...} 

一个类可以在继承另一个类的同时实现多个接口,并且多个接口之间需要使用英文逗号分隔。接口的实现类,必须实现接口中的所有抽象方法,否则会编译报错。接口与接口之间还可以时继承关系用extends关键字实现。
接口特点归纳:
(1)在JDK8之前,接口中的方法都必须是抽象的,并且方法不能包含方法体。在调用抽象方法时,必须通过接口的实现类的对象才能调用实现方法。从JDK8开始,接口中的方法除了包含抽象方法外,还包含默认方法和静态方法,默认方法和静态方法都可以有方法体,并且静态方法可以直接通过“接口.方法名”来调用。
(2)当一个类实现接口时,如果这个类是抽象类,只需实现接口中的部分抽象方法即可,否则需要实现接口中的所有抽象方法。
(3)一个类可以通过implements关键字同时实现多个接口,被实现的多个接口之间要用英文逗号隔开。
(4)接口之间可以通过extends关键字实现继承,并且一个接口可以同时继承多个接口,接口之间用英文逗号隔开。
(5)一个类在继承一个类的同时还可以实现接口,此时extends关键字必须位于implements关键字之前。

//先继承,再实现
class A extends B implements C {
}
多态
  • 多态概述

在Java中,多态是指不同类的对象在调用同一个方法时所呈现出的多种不同行为。通常来说,在一个类中定义的属性和方法被其他类继承或重写后,当把子类对象直接赋值给父类引用变量时,相同引用类型的变量调用同一方法将呈现出多种不同形态。
Java的多态性是由类的继承、方法重写以及父类引用指向子类对象体现的。由于一个父类可以有多个子类,多个子类都可以重写父类方法,并且多个不同的子类对象也可以指向同一个父类;这样,程序只有在运行时才能知道具体代表的是哪个子类对象,这就体现了多态性。
有两个不同的子类继承自同一父类,分别创建一个对象同时指向一个父类对象并调用不同的重写方法,程序在编译时自动识别具体的子类对象,从而选择性的调用对应的方法。
多态不仅解决了方法同名的问题,而且还使程序变得更加灵活,从而有效的提高程序的可扩展性和可维护性。

  • 对象的类型转换
    向上转型:将子类对象当做父类类型使用。
    向下转型:把父类引用转成子类引用(强制类型转换)。
    在进行对象向下类型转换时,必须转换为本质类型,否则转换时会出现错误。为了避免这种问题,可以使用instanceof来判断一个对象是否为某个类(或接口)的实例或者子类的实例。
对象(或者对象引用变量) instanceof 类(或接口)
内部类

当继承和接口同时存在时,需要先继承,后实现;Java 中,类只能单继承,但接口可以多继承。
匿名内部类没有类名,因此无法通过“外部类对象 .new 内部类()”的方式生成独享。
静态内部类只能访问外部类的静态成员。
在 JDK8.0 以前,局部内部类在访问包含它的方法中的变量时,必须给这个变量加 final 修饰;但自 JDK8.0 以后,JDK 会自动添加 final,因此可以省略 final。
抽象类和接口都不能直接被实例化,只能实例化他们的子类或者实现类。接口可以继承多个父接口。接口中的方法必须是抽象方法,接口中的“变量”只能是常量的形式。
抽象类里既可以含有抽象方法,也可以含有普通方法,但是不能只包含普通方法。Java 只支持单继承。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值