计算机基础知识——面向对象:封装+继承+多态整理

在这里插入图片描述

面向对象三大特性:封装、继承、多态。

1.封装

将一系列相关事物的共同的属性和行为提取出来,放到一个类中,同时隐藏对象的属性和实现细节,仅对外提供公共的访问方式。
【JavaBean类就可以看作是封装的完美案例。】

setter和getter

其实指的分别是setXxx和getXxx两个函数。setXxx可以修改对应属性的值,而getXxx则可以获取对应属性的值。
他俩能给private属性赋值个取值。

this

每一个创建的对象都有一个this属性,指向该对象本身(类似于指针,但在Java中叫做引用)

  1. 用法:
    ①this.属性名; (可调用当前对象的属性,this.属性名就是当前对象的属性)
    ②this.方法名(参数); (可调用当前对象的方法)
    ③知识延申 :
    PS : this(参数列表) 可以访问本类的构造器。但要注意:Δ此时this后不需要加"."。Δ该途径只能在构造器中使用,且使用时必须置于构造器的首句。我们称之为“构造器的复用”。
    可以解决形参名与属性名的重名问题。
package knowledge.define;
 
public class Phone {
//成员变量:
    private int age;  
 
    //this 关键字对于属性的应用:
    public void pintAge () {
        int age = 10;

        System.out.println("1:" + age);
        System.out.println("2:" + this.age);
    }
}

 
public class
TestPhone {
    public static void main(String[] args) {
//1.创建对象
        Phone p = new Phone();
//2.调用成员方法
        p.pintAge();
    }
}

1:10
2:0
因为this.age没有setAge赋值,整型默认值为0

构造器

构造器,也叫构造方法,指用来帮助创建对象的方法,但仅是帮助。它不是用来创建新对象的,而是完成对新对象的初始化
实际上是:new关键字来创建对象,并在堆内存中开辟空间,然后使用构造器完成对象的初始化。

  1. 构造器需要满足的要求:
    构造方法名必须与类名相同!(包括大小写)
    构造方法没有返回值!(但是也可以在方法内部写一个return)
  2. 当类中没有定义任何构造器时,该类默认隐含一个无参构造。这也是为什么我们之前写过的类中没有定义构造器,却依然可以创建该类的对象,因为系统默认给出了无参构造,所以就会以默认的无参构造对新对象进行初始化
  3. 构造器可以重载,就和方法一样,同一个类中可以定义多个构造器。
  4. 构造器是在执行new关键字的时候,由系统来完成的,即在创建对象时,系统会自动匹配并调用该类的某个构造器完成对对象的初始化。
    构造器示例:
public class Phone {
    private int age = 11;
 
    //公有的空参构造   (重点)
    public Phone() {
        System.out.println("这是空参构造,成功调用此构造时打印这句话");
    }
    public Phone(int age) {
        System.out.println("这句话打印出来,说明带参构造被成功调用");
        this.age = age;
    }

    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
}
public class TestKunKun {
    public static void main(String[] args) {
        //调用有参构造
        Phone phone1 = new Phone(18);
        //调用无参构造
        Phone phone2 = new Phone();
        
    }
}

2.继承

Java中继承的特点:

  1. 仅支持单继承。每个类最多有且只能继承一个类,不能同时继承多个类。但是,Java支持多层继承。 多层继承指当父类衍生出一个子类后,该子类可以作为父类继续衍生出它的子类.
  2. 父类私有成员子类无法继承。发生继承关系后,子类拥有了父类的非私有成员。
  3. 父类构造器子类不能继承。构造器用于初始化对象。父类构造器用于初始化父类对象,子类构造器用于初始化子类对象。

super关键字

  1. 类似于this关键字,super关键字也是一个指针,当然了,在Java中叫做引用。
    this是一个指向当前对象的引用。而super则是指向当前对象父类的引用(即父类内容内存空间的标识)。
    当new关键字创建子类对象时,子类对象的堆空间中会有一部分用于存放父类的内容,即继承自父类的非私有成员。super就指向这么一部分。可以理解为,super指向的部分是在this指向的部分的范围内。在使用时,this从本类开始找,super从父类开始找。
  2. 直接访问父类变量的方式 : super.父类变量名 (仅能访问非私有属性,所以是直接访问)
  3. new关键字创建对象后,对象初始化顺序:
    先初始化父类内容,再初始化子类内容。(原因是创建子类对象时,优先调用父类的构造器
  4. java中查找变量的顺序:
    在这里插入图片描述
  5. this关键字解决了局部变量和本类成员变量的命名冲突问题。this关键字使得我们可以在局部变量存在的情况下,避开Java就近原则的约束,在局部位置使用成员变量。
    super关键字,就是从父类开始找,在局部位置使用父类成员变量。

继承关系中构造器的使用

继承设计中的基本思想 : 父类的构造器初始化父类内容,子类的构造器初始化子类内容。
(1)创建子类对象时,优先调用父类的构造器。
(2)子类构造器的第一行,默认隐含语句super(); 用于调用父类的默认无参构造。
(3)当父类有参无参都有,子类构造器的使用情况 : 无参对无参,有参对有参。即,在子类无参构造中通过“super();” 调用父类的无参构造;在子类有参构造中通过“super(参数);” 调用父类的有参构造。

方法重写

重写必须满足返回值类型、方法名,参数列表都相同!即——外壳不变,内部重写。
可以用@Override注解来标注。
① 父类私有方法不能被重写。
② 子类方法访问权限不能小于父类方法,即访问权限 : 子类 ≥ 父类。(本文后面我们就会讲到Java四大访问修饰符)
③ 子类不能比父类抛出更大的异常

方法重写和方法重载的区别 :

  1. 重载:是指不同的函数使用相同的函数名,但是函数的参数个数或类型不同。调用的时候根据函数的参数来区别不同的函数。重载是在一个类中。
  2. 重写:是指在派生类中重新对基类中的虚函数(注意是虚函数)重新实现。即函数名和参数都一样,只是函数的实现体不一样。重写是子类与父类之间。
    图片来自https://blog.csdn.net/TYRA9/article/details/128523078

Java四大访问权限修饰符 :

访问权限修饰符指的是用来修饰成员变量,成员方法和类,来确定它们的访问权限的。
分别是private、默认、protected,public。
(1)private修饰的成员只能在本类使用。
(2)public修饰的成员可以被所有类使用。
(3)默认修饰符,指的就是没写修饰符。默认修饰符修饰的成员允许在当前所在包下其他类使用。
(4)protected修饰符修饰的成员除了可以在本包下使用,在其子类中也可以使用。
四大修饰符按照根据访问权限从小到大的原则依次是 : private < 默认 < protected < public。

延申(关于类和源文件的关系) :

① 一个Java源文件中可以定义多个类,源文件的基本组成部分是类。
②源文件中定义的类,最多只能有一个类被public修饰,其他类的个数不限。
③如果源文件中有被public修饰的类,那么源文件名必须与该类类名保持一致
④如果源文件中没有被public修饰的类,那么源文件名只要符合命名规范就可以。
⑤main函数不一定非得写在public修饰的类中,也可以将main函数写在非public修饰的类中,然后通过指定运行非public类,这样入口方法就是非public类的main方法。

————————————————
部分内容摘自:https://blog.csdn.net/TYRA9/article/details/128523078

3.多态

多种形态,具体点就是去完成某个行为,当不同的对象去完成时会产生不同的状态。

条件

在Java中要实现多态,必须要满足如下几个条件,缺一不可:

  1. 必须在继承体系下
  2. 子类必须要对父类方法进行重写
  3. 通过父类的引用调用重写的方法

向上转型和向下转型

向上转型:实际就是创建一个子类对象,将其当成父类对象来使用。
语法格式:父类类型 对象名 = new 子类类型()
(1)直接赋值

Parent c = new Child();

(2)方法的参数,传参的时候进行向上转型

    public static void fun(Parent p)
    {
    //...
    }

(3)返回值转型

    public static Child fun1()
    {
        Child c = new Child();
        return c;
    }

向下转型:将一个子类对象经过向上转型之后当成父类方法使用,再无法调用子类的方法,但有时候可能需要调用子类特有的方法,此时:将父类引用再还原为子类对象即可,即向下转换。
注:向下转型用的比较少,而且不安全,万一转换失败,运行时就会抛异常。Java中为了提高向下转型的安全性,引入了 instanceof ,如果该表达式为true,则可以安全转换。

重写

外壳不变,核心重写! 重写的好处在于子类可以根据需要,定义特定于自己的行为。 也就是说子类能够根据需要实现父类的方法。

方法重写的规则:

  1. 返回值类型,方法名 ,参数列表 必须是一样的(返回值是父子关系,可以构成重写叫协变)
  2. 访问权限不能比父类中被重写的方法的访问权限更低。例如:如果父类的一个方法被声明为public,那么在子类中重写该方法就不能声明为protected。
  3. 被private修饰的方法是不可以被重写的
  4. 被static修饰的方法是不可以被重写的
  5. 被final修饰的方法是不可以被重写的
  6. 构造方法不能被重写的

final关键字

final:最终的、不可改变的。可用于修饰类、方法、变量。
类:被修饰的类,不能被继承
方法:被修饰的方法,不能被重写
变量:被修饰的变量,有且只能被赋值一次

public final class String 、public final class Math 、public final class Scanner 等,很多我们学习过的类,都是被final修饰的,目的就是供我们使用,而不让我们所以改变其内容。

  1. 修饰变量-成员变量
    成员变量如果被final修饰,一旦有了初始值 就不能被重新赋值。
    由于成员变量具有默认值,用final关键字修饰后 不会再给默认值,必须手动赋值,否则会报错。
    因此必须手动初始化,有两种初始化方式——显示初始化和构造方法初始化。

(1)直接赋值

public class Person {
    private final String name = "Jenny";
}

(2)构造方法赋值

public class Person {
    //对于final类型的成员变量,有两种初始化方式(赋值方式),显示初始化和构造方法初始化,只能选其中一个

    // 定义成员变量时指定默认值,合法。
    final String name = "Jenny";
    final int num;
    public Person() {
        // 在构造器中分配初始值
        num = 20;
    }
    public Person(int num) {
        // 在构造器中分配初始值
        this.num = num;
    }
}

static关键字

static是静态的意思,可用来修饰 成员方法、成员变量。static修饰后的变量、方法,可以被类的所有对象共享
static修饰成员变量之后,这个变量被称为类变量或静态成员变量;无static修饰的成员变量是属于每个对象的,这个变量被称为实例变量
static修饰方法之后,这个方法被称为类方法或静态方法;无static修饰的成员方法是属于每个对象的,这个成员方法也叫做实例方法

推荐以 对象.静态成员变量类名.静态方法的形式来访问

public class Employee {
    //静态成员变量,属于类,只有一份
    public static String companyName = "abc";   
    public static void work() {
        System.out.println("我们都在" + companyName + "公司工作");
    }
    //实例变量
    private String name;
    private Integer age;
    public void achive() {
        System.out.println(name + "实现大成就");
    }
}

public static void main(String[] args) {
    System.out.println(Employee.companyName); //abc
    Employee.companyName = "learn"; //直接用类来访问
    System.out.println(Employee.companyName);  //learn
    Employee.work(); //直接用类来访问
    Employee employee1 = new Employee("zhangsan", 18);//实例化对象来访问
    System.out.println(employee1.getAge()); //18
    employee1.achive();//对象来访问
}

注:
(1)静态方法只能访问静态成员。不能直接访问实例成员
若想要使用静态方法调用非静态方法,只需要实例化new一个类对象,此时jvm虚拟机就会为对象开辟一块内存,该类的所有方法也随之被存储到内存当中。此时静态方法和非静态方法都在内存当中,所以在静态方法中可以使用对象去调用一个非静态方法。
(2)实例方法可以访问静态成员,也可以访问实例成员
(3)静态方法中是不可以出现this关键字的。this指当前对象,静态方法中不用声明实例对象
(4)static方法不能被子类重写,在子类中定义了和父类完全相同的static方法,则父类的static方法被隐藏,Son.staticmethod()或new Son().staticmethod()都是调用的子类的static方法,如果是Father.staticmethod()或者Father f = new Son(); f.staticmethod()调用的都是父类的static方法

在java中,程序执行时 类的字节码文件会被加载到内存中,如果类没有创建对象 类的成员变量则不会分配到内存;
但对于被static修饰的静态变量/方法,堆中有一个专属的静态变量区,当JVM虚拟机将字节码加载到内存时,会为静态变量/方法在堆中分配出一段空间用于放置值,即静态变量/方法跟随类加载而加载

抽象类

  1. 抽象类概念
    在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。
    我们可以把它设计成一个 抽象方法(abstractmethod), 包含抽象方法的类我们称为 抽象类(abstract class)

  2. 抽象类语法
    在Java中,一个类如果被 abstract 修饰称为抽象类,抽象类中被 abstract 修饰的方法称为抽象方法,抽象方法不用给出具体的实现体。

abstract class A{
    abstract void  fun();
}

class B extends A{
    void  fun()
    {
        System.out.println("B fun");
    }

注意:抽象类也是类,内部可以包含普通方法属性,甚至构造方法

  1. 抽象类特性
  2. 使用abstract修饰的方法称为抽象方法
  3. 使用abstract修饰的类称为抽象类
  4. 抽象类是不可以实例化的
  5. 抽象类当中可以和普通类一样定义成员变量和成员方法
  6. 当一个普通的类继承这个抽象类,那么需要重这个抽象类当中的所有的抽象方法!!!
  7. 抽象类的出现就是为了被继承!!!
  8. abstract 和final不能共存
  9. 被private static 修饰的抽象方法也是不可以的

接口

接口

  1. 接口的概念
    接口就是公共的行为规范标准,大家在实现时,只要符合规范标准,就可以通用。在Java中,接口可以看成是:多个类的公共规范,是一种引用数据类型。
  2. 语法规则
    接口的定义格式与定义类的格式基本相同,将class关键字换成interface关键字,就定义了一个接口。
public interface 接口名称{
	// 抽象方法
	public abstract void method1(); // public abstract 是固定搭配,可以不写
	public void method2();
	abstract void method3();
	void method4();
	// 注意:在接口中上述写法都是抽象方法,跟推荐method4,代码更简洁
}
  1. 接口使用
    接口不能直接使用,必须要有一个"实现类"来"实现"该接口,实现接口中的所有抽象方法
public class 类名称 implements 接口名称{
// ...
}
// USB接口
public interface USB {
	void openDevice();
	void closeDevice();
}
// 鼠标类,实现USB接口
public class Mouse implements USB {//实现接口
	@Override
	public void openDevice() {//实现方法
	System.out.println("打开鼠标");
	}
	@Override
	public void closeDevice() {
	System.out.println("关闭鼠标");
	}
	public void click(){
	System.out.println("鼠标点击");
	}
}
  1. 接口特性
    (1).接口当中不能有被实现的方法,意味着只能有抽象方法两个方法除外:一个是static修饰的方法一个是被default修饰的方法.
    (2).接口当中的抽象方法,默认都是public abstract修饰的
    (3).接口当中的成员变量,默认都是public static final修饰的
    (4).接口不能进行实例化
    原文链接:https://blog.csdn.net/weixin_66484088/article/details/135323441
  2. 在Java中,类和类之间是单继承的,但是一个类可以实现多个接口接口与接口之间可以多继承
interface IRunning {
void run();
}
interface ISwimming {
void swim();
}
// 两栖的动物, 既能跑, 也能游
interface IAmphibious extends IRunning, ISwimming {
}
class Frog implements IAmphibious {
...
}

  1. 抽象类和接口的区别
    抽象类和接口都是 Java 中多态的常见使用方式. 都需要重点掌握. 同时又要认清两者的区别(重要!!! 常见面试题).
    核心区别: 抽象类中可以包含普通方法和普通字段, 这样的普通方法和字段可以被子类直接使用(不必重写),
    而接口中不能包含普通方法, 子类必须重写所有的抽象方法.

  2. Object类
    Object是默认类,除Object类外所有的类都有继承关系,默认继承Object类。所以可以直接使用Object的方法(当然有些需要重写方法)。
    比如使用Object类中的equals

    对象比较equals方法
    a.如果左右两侧是基本类型变量,比较的是变量中值是否相同
    b.如果左右两侧是引用类型变量,比较的是引用变量地址是否相同
    c.如果要比较对象中内容,必须重写Object中的equals方法,因为equals方法默认也是按照地址比较的:

class Preson{ // 默认继承Object类
    String name;
    int age;
    public Preson(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
}
public static void main(String[] args) {
        Preson  a = new Preson("张三",18);
        Preson  b = new Preson("张三",18);
        System.out.println(a.equals(b));
    }

没有重写就是两个类对象比较地址是否相同,为False
重写:后就是True

    @Override
    public boolean equals(Object obj) {
        Preson b = (Preson) obj;
        return this.age==b.age&&this.name.equals(b.name);
    }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值