关于java面向对象做的一些笔记


要理解面向对象思想,我们先要知道什么是对象?

《Java编程思想》中提到“万物皆为对象”的概念。它将对象视为一种奇特的变量,它除了可以存储数据之外还可以对它自身进行操作。它能够直接反映现实生活中的事物,例如人、车、小鸟等,将其表示为程序中的对象。每个对象都具有各自的状态特征(也可以称为属性)及行为特征(方法),java就是通过对象之间行为的交互来解决问题的。

面向对象就是把构成问题的事物分解成一个个对象,建立对象不是为了实现一个步骤,而是为了描述某个事物在解决问题中的行为。

而类是从对象的属性和行为特征抽象出来的,对象是类的一个实例。比如说马,马是指一个概念,你可以具体到某一匹马,那么,这匹马就是马类的一个对象

创建类的格式

class 类名(首字母大写){
	属性
	方法
}

创建对象并给属性赋值,调用函数

类名 变量名 = new 类名();
变量名.属性 = 变量;
变量名.方法();
class Person{
	String name;
	int age;
	
	public void run(){
		System.out.println("奔跑");
	}
}

创建一个人的类,具有名字和年龄属性,还具有奔跑行为

public static void main(String[] args) {
        Person per = new Person();
        per.name = "里斯";
        per.age = 18;
        per.run();
    }

在main方法中创建对象,并赋值,调用函数

一、类具有三大特征:封装,继承,多态

1.封装

场景需求:试想一下,当你给一个对象赋值-5岁的时候,这在现实中是不可能的,但是在程序中是成功执行。
总结一下:核心思想就是“隐藏细节”、“数据安全”,将对象不需要让外界访问的成员变量和方法私有化,只提供符合开发者意愿的公有方法来访问这些数据和逻辑,保证了数据的安全和程序的稳定。所有的内容对外部不可见。
于是,我们将类的属性私有化(private),在内部进行处理,不允许外部通过赋值的方法进行修改,可以通过调用方法进行修改,方法内部进行一定处理,即可达到要求。
封装性的体现

  1. Java规定的4种权限(从小到大排列):private、缺省(不加修饰符)、protected、public
  2. 4中权限可以用来修饰累计类的内部结构:属性、方法、构造器、内部类
    修饰类的话,只能使用:缺省,public

封装举例

	private int age;
    
    public void setAge(int age){
        if ( this.age >0 && this.age < 150){
            this.age = age;
        }else {
            System.out.println("不符合要求");
        }
    }

定义变量age只有小于150大于0才能赋值成功

2.继承

场景:有一个类有很多满足你的要求,你是要把这个类赋值下来吗?不需要赋值,使用继承,就拥有了他的大部分功能。

总结:子类可以继承父类的属性和方法,并对其进行拓展。将其他的功能继承下来继续发展 。

格式
class A extends B{}

A:子类,派生类,subclass

B:父类,基类,superclass
继承举例

public class Demo01 extends Person{
    public static void main(String[] args) {
        Demo01 de = new Demo01();
        de.name = "li";
        de.print();
    }
}

class Person{
    String name;

    public void print(){
        System.out.println(name);
    }
}

注意:一旦父类A继承父类B以后,子类A中就获取了父类B中声明的所有的属性和方法。特别的,子类中声明为private的属性或方法,子类继承父类之后,仍然认为获取了父类中私有的结构,只有因为封装性的影响,使得子类不能直接调用父类的结构而已
规定

  1. 一个类可以被多个子类继承。
  2. Java中类的单继承性,一个类只能有一个父类
  3. 父子类是相对的概念。
  4. 子类继承父类之后,就获取了直接父类以及所有简介父类中声明的属性和方法

如果我没有显示的声明一个类的父类的话,则此类继承于java.lang.Object类

3.多态

理解多态性:可以理解为一个事物的多种形态
何为多态性:对象的多态性,父类的引用指向子类的对象(或子类的对象赋给父类的引用)
多态性的使用前提

  1. 类的继承关系
  2. 父类方法的重写

格式:父类类型 变量名=new 子类类型();
多态举例

public class Demo01 extends Person{

    @Override
    public void print() {
        System.out.println("Demo01");
    }

    public static void main(String[] args) {
        Person per = new Demo01();
        per.print();
    }
}

class Person{
    String name;

    public void print(){
        System.out.println(name);
    }
}

虚拟方法调用(多态情况下):子类中定义了与父类同名同参数的方法,在多态情况下,将此时父类的方法成为虚拟方法,父类根据赋给它的不同子类对象,动态动用属于子类的该方法,这样的方法调用在编译器是无法确定的
运行时类型:在运行时才知道行为,例如随机数,只有运行时才知道是多少。
编译式类型:不运行就知道干啥
向下转型:有了对象的多态性以后,内存中实际上是加载了子类特有的属性和方法的,但是由于变量声明为父类类型,导致编译时,只能调用父类中声明的属性和方法,子类特有的属性和方法不能使用.。因此可以把多态化的这个对象转为子类对象,调用子类属性和方法

二、构造器

首先构造器在创建类的对象时就出现了,就是类后面的括号。
用处:在创建对象时,初始化类的属性。
格式:权限修饰符 类名(形参列表){}
举例

public class Demo01{
    public static void main(String[] args) {
        Person p1 = new Person("李四",18);
    }
}

class Person{
    String name;
    int age;
	
    public Person(String name, int age){
        this.name = name;
        this.age = age;
    }
    // 当初始化类信息之后,会覆盖原先的无参构造器,一般情况下,会重新协商
    // 可以定义多个构造器,在调用时会根据参数不同调用不同的构造器,在一个构造器内部还可以调用其他构造器,在this中说明如何调用
	public Person(){
    }
	
}

注意:如果没有显示的定义类的构造器的话,则系统默认提供一个空参的构造器。当你自己创建有参构造器之后,会覆盖原先的无参构造器

三、this关键字

用来区分类的属性与传进来的参数
格式:this.属性 = 形参
this调用构造器

  1. 我们在类的构造器中,可以显示的使用“this(形参列表)”方式,调用本类中指定的其他构造器
  2. 构造器中不能通过“this(形参列表)”方式调用自己
  3. 规定:“this(形参列表)”必须声明在当前构造器的首行
  4. 构造器内部,最多只能声明一个“this(形参列表)”,用来调用其他构造器
    举例
class Person{
    String name;
    int age;
    
    public Person(){};
    
    public Person(String name){
        this.name = name;
        
    }

    public Person(String name, int age){
    	// 调用其他构造器
        this(name);
        this.age = age;
    }

}

四、super关键字

场景:当父类的方法被子类重写之后,还想要使用父类的这个方法,子父类出现同名的属性
super关键字的使用

  1. super理解为:父类的
  2. super可以用来调用:属性、方法、构造器
1、super的使用,调用父类属性,方法
  1. 我们可以在子类的方法或构造器中,通过使用“super.属性”或“super.方法”的方式,显式的调用父类中声明的属性或方法。但是,通常情况下,我们习惯省略“super.”
  2. 特殊情况:当子类和父类中定义了同名的属性时,我们要想在子类中调用父类中声明的属性,则必须显式的使用“super.属性”的方式,表明调用的是父类中声明的属性。
  3. 特殊情况:当子类重写了父类中的方法以后,我们要想在子类中调用父类中声明的方法,则必须显式的使用“super.方法”的方式,表明调用的是父类中声明的方法。
    举例
public class Demo01 extends Person{
    public static void main(String[] args) {
        Demo01 de = new Demo01();
        de.print();
        //父类的print
        //子类的print
    }

    @Override
    public void print() {
        super.print();
        System.out.println("子类的print");
    }
}

class Person{
    String name;
    int age;

    public void print(){
        System.out.println("父类的print");
    }
}
2.super调用构造器
  1. 我们可以在子类的构造器中显示的使用“super(形参列表)”的方式,调用父类中声明的指定的构造器
  2. “super(形参列表)”的使用,必须声明在子类构造器的首行
  3. 我们在类的构造器中,针对于“this(形参列表)”或“super(形参列表)”只能二选一,不能同时出现
  4. 在构造器的首行,没有显式的声明“this(形参列表)”或“super(形参列表)”,则默认调用的是父类中空参的构造器
  5. 在类的多个构造器中,至少有一个类的构造器中使用了“super(形参列表)”,调用父类中的构造器
    当父类不存在空参构造器,而子类没有使用其他构造器时,就会报错
    举例
public class Demo01 extends Person{
    char gender;
    
    public Demo01(String name, int age, char gender){
    	// 调用父类构造器
        super(name,age);
        this.gender = gender;
    }
}

class Person{
    String name;
    int age;

    public Person(){};

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

static关键字

用处:.static可以用来修饰:属性,方法,代码块,内部类。存在于方法区的静态域中

使用static修饰属性:静态变量

属性,按是否使用static修饰,分为:静态属性和非静态属性(实例变量)

静态属性:我们创建了类的多个对象,每个对象都独立的拥有一套类中的非静态属性,当修改其中一个对象中的非静态属性时,不会导致其他对象中同样的属性值的修改

静态变量:我们创建了类的多个对象,多个对象共享同一个静态变量,当通过某一个对象修改静态变量时,会导致其他对象调用此静态变量时,是修改了的。

static修饰属性的其他说明

  1. 静态变量随着类的加载而加载,可以通过”类.静态变量”的方式进行调用
  2. 静态变量的加载要早于对象的创建
  3. 由于类只会加载一次(创建完对象之后,会把类缓存到方法去),则静态变量在内存中也只会存在一份:存在方法区的静态域中
static修饰方法,静态方法
  1. 随着类的加载而加载,可以通过“类.静态方法”的方法进行调用

  2. 静态方法中,只能调用静态的方法或属性

    非静态方法中,既可以调用非静态的方法或属性,也可以调用静态的方法或属性
    举例

public class Demo01{
    public static void main(String[] args) {
//        Person.name = "张三";
        System.out.println(Person.name); // "张三"
        Person.print();// "static"
        Person p1 = new Person();
        p1.name = "李四";
        Person p2 = new Person();
        System.out.println(p2.name); // 李四

    }
}

class Person{
    static String name = "张三";
    int age;
    static void print(){
        System.out.println("static");
    }

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

}
static注意点

在静态的方法内,不能使用this关键字,super关键字

关于静态属性和静态方法的使用,大家都从生命周期的角度去理解

如何使用

开发中,如何确定一个属性是否要声明为static?

属性是可以被多个对象共享的,不会随着对象的不同而不同的

开发中,如何确定一个方法是否要声明为static?

操作静态属性的方法,通常设置为static

工具类中的方法,习惯上声明为static。比如:Math,Arrays,Collections

抽象方法概念:随着继承层次中一个个新子类的定义,类变得越来越具体,而父类则更一般,更通用。类的设计应该保证父类和子类能够共享特征。有时将一个父类设计的非常抽象,以至于它没有具体的实例,这样的类叫做抽象类
abstract:抽象的
abstract可以用来修饰的结构:类,方法
abstract修饰类:抽象类

  1. 此类不能实例化
  2. 抽象类中一定有构造器,便于子类实例化时调用(设计:子类对象实例化的全过程)
  3. 开发中,都会提供抽象类的子类,让子类对象实例化,完成相关的操作

abstract修饰方法,抽象方法

  1. 抽象方法只有方法的声明,没有方法体

  2. 包含抽象方法的类,一定是一个抽象类。反之,抽象类中可以没有抽象方法的

  3. 若子类重写了父类所有的抽象方法后,此子类方可实例化

    若子类没有重写父类中所有抽象方法,则子类一定是抽象类

抽象类与抽象方法

抽象类使用举例

public class Demo01 extends animal{
    
    // 重写抽象方法
    @Override
    public void eat() {
        System.out.println("Demo01");
    }
}

//抽象类
abstract class animal{
    abstract public void eat();
}

抽象类继承举例

public class Demo01 extends Pig{

    // 重写间接父类抽象方法
    @Override
    public void eat() {
        System.out.println("Demo01");
    }
    // 重写父类抽象方法
    @Override
    public void run() {
        
    }
}

//抽象类继承
abstract class Pig extends animal{
    abstract public void run();
}

//抽象类
abstract class animal{
    abstract public void eat();
}

通过单继承,继承父类,父类上面还有父类,并且是抽象类,需要重写全部抽象类的抽象方法。
注意

  1. abstract不能用来修饰:属性,构造器等结构
  2. abstract不能用来修饰私有方法,静态方法,final的方法,final的类

接口

接口格式:interface 类名{}

如何定义接口

定义接口中的成员
JDK7及以前:只能点定义全局常量和抽象方法

  • 全局常量:public static final的,但是书写时,可以省略不写(但是照样有)
  • 抽象方法:public abstract的

** JDK8**:除了定义全局常量和抽象方法之外,还可以定义静态方法,默认方法(略)
接口内部只能定义public static final属性,public abstract抽象方法,当你没有带上时,会自动帮你填上,
接口举例

public class USBTest {
	public static void main(String[] args) {
		
		Computer com = new Computer();
		//1.创建了接口的非匿名实现类的非匿名对象
		Flash flash = new Flash();
		// 多态调用
		com.transferData(flash);
	}
}

class Computer{
	
	public void transferData(USB usb){//USB usb = new Flash();
		usb.start();
		
		System.out.println("具体传输数据的细节");
		
		usb.stop();
	}
	
	
}

interface USB{
	//常量:定义了长、宽、最大最小的传输速度等
	
	void start();
	
	void stop();
	
}

class Flash implements USB{

	@Override
	public void start() {
		System.out.println("U盘开启工作");
	}

	@Override
	public void stop() {
		System.out.println("U盘结束工作");
	}
	
}

JDK8:除了定义全局常量和抽象方法之外,还可以定义静态方法,默认方法
举例



public class SubClassTest {

    public static void main(String[] args) {
        SubClass s = new SubClass();
//        s.method1();
//        SubClass.method1();
//        知识点1:接口中定义的静态方法,只能通过接口调用
        CompareA.method1();
        // 知识点2.通过实现类的对象,可以调用接口中的默认方法
        //如果实现类重写了接口的默认方法,调用时,仍然调用的是重写以后的方法 --->类优先原则
        s.method2();
        // 知识点3如果子类(或实现类)继承的父类和实现的接口中声明了同名同参的方法,那么子类在没有重写此方法的情况下,默认调用的是父类中的同名同参的方法 --》类优先原则
        // 知识点4 如果实现类实现了多个接口,而这多个接口中定义了同名同参的默认方法,那么在实现类没有重写此方法的情况下,报错 --》接口冲突
        s.method3();

    }

}

class SuperClass{
    public void method3(){

    }
}
//class SubClass extends SuperClass implements CompareA,CompareB
class SubClass implements CompareA,CompareB{
    //重写CompareA接口中的默认方法
    @Override
    public void method2() {
        System.out.println("广州");
    }
}

interface CompareA {

    public static void method1(){
        System.out.println("北京");
    }

    public default void method2(){
        System.out.println("上海");
    }

    public default void method3(){
        System.out.println("昆明");
    }
}
interface CompareB{
    default void method3(){
        System.out.println("上海");
    }
}

注意
  1. 接口中不能定义构造器的!意味着接口不可以实例化
  2. Java开发中,接口通过让类区实现(implements)的方式来使用
    如果实现类覆盖了接口中的所有抽象方法,则此实现类可以实例化
    如果实现类没有覆盖接口中所有的抽象方法,则此实现类是一个抽象类
  3. 接口与接口之间可以继承,多继承
  4. Java中,接口和类是并列的两个结构
  5. 接口的具体使用,体现多态性
  6. Java类可以实现多个接口 —>摸不了Java但继承性的局限性
    格式:class 类名 extends 父类 implements 接口1,接口2{}
    接口与接口之间用英文逗号隔开

接口规范

接口,实际上可以看作是一种规范。体现了现实世界中”如果你是/要…则必须能…“的思想。继承是一个”是不是“的关系,而接口实现则是”能不能“的关系。

比如说:它给你说了你要做什么,第一,你要怎么,第二,你要怎么。然后怎么去做,是你的事,统一了任务。然后去完成。

所以,接口的只要用途就是被实现类实现(面向接口边框)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值