Java基础要点笔记2面向对象(尚硅谷)

写在前面:Java基础系列文章

Java基础要点笔记1(尚硅谷)
Java基础要点笔记2面向对象(尚硅谷)
Java编程之异常处理
Java编程之多线程
Java编程之常用类
Java编程之枚举类&注解
Java编程之Java集合
Java编程之泛型
Java编程之IO流
Java编程之网络编程
Java编程之反射机制
Java编程之Java8&9&10&11新特性
十大排序算法
关于设计模式

Java面向对象编程(尚硅谷)

1. Java类及类成员(属性、方法、构造器、代码块、内部类)

1.1 概述

  类就是一个抽象的概念,对象就是一个具体的实例,类成员有类属性和类方法,通过“对象.属性”或“对象.方法”调用对象的结构

  注:Person p3 = p1 ; // 将p1变量保存的对象地址赋给p3,导致p1和p3指向堆空间中的同一个对象实体,一个属性的修改,另一个也会进行相应的修改

1.2 对象的内存解析(重点)

  主要介绍运行时数据区的三个部分:
内存解析
堆Heap: 此内存区域的唯一目的就是存放对象实例,所有对象实例以及数组都要在堆上分配;

虚拟机栈Stack: 即通常所说的栈,用于存放局部变量等,局部变量表存放了编译器可知长度的各种基本数据类型、对象引用(reference类型,它不等同于对象本身,是对象在堆内存的首地址),方法执行完,自动释放;

方法区Method Area: 用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
在这里插入图片描述
为了加深理解,再附一张对象数组的内存解析图:
对象数组内存解析
引用类型的变量,只可能存储两类值:null 或 地址值(含变量的类型)
比如Phone的对象p,打印出来的值为
对象地址
  需要注意的是,编译完源程序以后,生成一个或多个字节码文件,我们使用JVM中的类加载器和解释器对生成的字节码文件进行解释运行。意味着,需要将字节码文件对应的类加载解析(是执行java xxx.exe的时候做的事情)

1.3 属性与局部变量

相同点在于定义的格式相同;先声明、后使用;变量都有其对应的作用域。
下面重点介绍一下不同点:

1.3.1 在类中声明的位置不同

  属性:直接定义在类中;

  局部变量:声明在方法内、方法形参、代码块内、构造器形参、构造器内部的变量;

1.3.2 关于权限修饰符的不同

  属性:可以在声明属性时,指明其权限,使用权限修饰符:peivate、public、protected

  局部变量:不可以使用权限修饰符

1.3.3 默认初始化值的情况

  属性:根据其类型,都有默认初始化值
  整型(byte、short、int、long) 0
  浮点型(float、double) 0.0
  字符型(char) 0或’\u0000’
  布尔型(boolean) false
  引用数据类型(类、数组、接口):null

  局部变量:没有默认初始值,调用局部变量之前一定要显示赋值,特别的,形参在调用时赋值即可。

1.3.4 在内存中加载的位置(重点)

  属性:加载到堆内存中(非static)

  局部变量:加载到栈空间

  注:解释一下堆共享和栈共享,参见https://blog.csdn.net/fox_bert/article/details/88367002,讲的挺清楚

  栈是数据共享,堆是线程共享(我理解的数据共享就是在栈中有1个3,然后多个int类型的变量指向它。而对于new出来的对象,比如String,每次new都会在堆中有新的地址,哪怕字符串的内容是一样的。)

  数据共享的有栈、常量池、寄存器、PC
  线程共享的有堆、全局变量、静态变量、方法区

1.4 类中方法的声明和使用

  ctrl+shift+t 可以搜索类文件,进到类文件后 ctrl+o 可以搜索方法

  权限修饰符 返回值类型 方法名(形参列表){
    // 方法体
  }
  注:static、final、abstract也可以修饰方法,后面再讲

如何理解“万事万物皆对象”?
在Java语言中,我们都将功能、结构等封装到类中,通过类的实例化,来调用具体的功能结构;当涉及到与前端、数据库在java层面交互时,都体现为类、对象。

1.5 匿名对象的使用

  1. 理解:在创建对象的时候,没有显式的赋给一个变量名,即为匿名对象
  2. 特征:匿名对象只能调用一次

1.6 再谈方法

1.6.1 方法的重载overload

定义: 在同一个类中,允许存在一个以上的同名方法,只要它们的参数个数或者参数类型不同即可。(与返回类型无关)

总结: “两同一不同”:同一个类、相同方法名;参数列表不同

1.6.2 可变形参的方法

jdk1.5提供了Varargs机制,允许直接定义和多个实参相匹配的形参。

  1. 格式:数据类型 … 变量名
  2. 特点:当调用可变个数形参的方法时,传入的参数个数可以是:0个、1个、2个…
  3. 可变个数形参的方法与本类中方法同名,形参不同的方法之间构成重载(如果有参数完全匹配的方法,那么会调用完全匹配的方法)
  4. 可变个数形参的方法与本类中方法同名,形参类型也相同数组之间不构成重载。换句话说,二者不能共存。
    publiv void show(String … strs){
    }
    public void show(String[] strs){
    }
    上面两个方法是一样的,遍历的时候,也是一样的,都是当做数组
  5. 可变个数形参在方法的形参中,必须声明在末尾
  6. 可变个数形参在方法的形参中,最多只能声明一个可变形参

这种可变形参的方法可以用在sql语句的where字句那,因为有时候不知道会匹配几个参数。
在这里插入图片描述
补充:对于可以自动类型转换的,可以在传参时传入,比如现在实参为int型,但是方法中没有形参为int型,有形参是double,那么也可以传进去。(多个参数也是一样,能自动类型转换,表示能够匹配,我在eclipse中试着是可以的)

1.6.3 方法参数的值传递机制★

关于变量赋值:

  1. 如果变量是基本数据类型,此时赋值的是变量所保存的数据值;
  2. 如果变量是引用数据类型,此时赋值的是变量所保存的数据的地址值;

值传递机制:

  1. 如果参数是基本数据类型,此时实参赋给形参的是实参真实存储的数据值
  2. 如果参数是引用数据类型,此时实参赋给形参的是实参存储数据的地址值
    在这里插入图片描述
    下面从内存角度理解下:
    在这里插入图片描述
    在这里插入图片描述
    拓展:
    第一道题目:
public class Test {
   
	public static void main(String[] args) {
   
		int a = 10 ;
		int b = 10 ;
		method(a,b) ;
		System.out.println("a="+a);
		System.out.println("b="+b);
	}
}

在不改变原本题目的前提下,如何写这个函数才能在main函数中输出a=100,b=200?
方法一:在method方法中输出,之后System.exit(0) ;
方法二:重置打印流,重写println

第二道题目:微软
定义一个int型的数组:int[] arr = new int[]{12,3,4,5,654,765,54,34,645,32} ;让数组的每个位置上的值除以首位置的元素,得到结果,作为该位置上的数值,遍历新的数组。
解法:倒着遍历

第三道题目:
int[] arr = new int[]{1,2,3} ;
System.out.println(arr) ; //地址值
char[] arr1 = new char[]{‘a’,‘b’,‘c’} ;
System.out.println(arr1) ; //abc
分析:这是跟println方法有关,传入的数组参数都是用Object来接收,但是对于char数组,是直接用char数组来接收的,会打印数组中的所有内容。

1.6.4 递归方法recursion

一个方法体内调用它自身。
例题:计算1-100之间所有自然数的和

public int getSum(int n){
   
	if(n==1){
   
		return 1 ;
	}else{
   
		return n + getSum(n-1) ;
	}
}

1.7 类的成员之四:代码块(初始化块)

在这里插入图片描述
这里需要注意的是: 代码块先于构造器执行
比如现在Leaf的父类是Mid,Mid的父类是Root,每个类中有静态代码块、非静态代码块,若干构造函数,现在new一个静态Leaf,它们的执行顺序为:
在这里插入图片描述

main方法除了是程序的入口之外,也是一个普通的静态方法,也是在执行main方法之前,如果main所在的类中有静态代码块,也会先于main方法

1.8 类的成员之四:内部类

内部类
成员内部类和局部内部类,在编译以后,都会生成字节码文件。

格式:

成员内部类:外部类$内部类.class

局部内部类:外部类$数字 内部类名.class

规定:局部内部类的方法中,如果调用局部内部类所声明的方法中的局部变量,则要求该变量声明为final。jdk7及以前的版本,要求显示声明为final,但是Jdk1.8之后可以省略final的声明(我理解如果被局部内部类调用了,那么在其他地方也不能修改了)
局部内部类不能有访问控制修饰符,且不能用static修饰,但是可以是abstract和final的

需要知道三个问题

  1. 如何实例化成员内部类的对象?
// 创建静态成员内部类实例
Person.Dog dog = new Person.Dog() ;
// 创建非静态成员内部类实例
Person p = new Person() ;
Person.Bird bird = p.new Bird() ;
  1. 如何在成员内部类中区分调用外部类的结构?
// 内部类中的方法
public void display(String name) {
   
	System.out.println(name) ;  // 方法形参
	System.out.println(this.name) ;   // 内部类的属性
	System.out.println(Person.this.name) ;   // 外部类的属性
}
  1. 开发中局部内部类的使用?
    内部类应用
    内部类总结:
    在这里插入图片描述

2. 面向对象的三大特征

2.1封装性

  • 高内聚:类的内部数据操作细节自己完成,不允许外部干涉
  • 低耦合:仅对外暴露少量的方法用于使用
    面试回答:隐藏对象内部的复杂性,只对外公开简单的接口,便于外界调用,从而提高系统的可扩展性、可维护性。

问题的引入:
  当我们创建一个类的对象以后,我们可以通过“对象.属性”的方式,对对象的属性进行赋值,这里,赋值操作要受属性的数据和存储范围的制约。除此之外,没有其他制约条件。但是,在实际问题中,我们往往需要给属性赋值加入额外的限制条件,这个条件就不能在属性声明时体现,我们只能通过方法进行限制条件大的添加。同时为了避免用户再使用“对象.属性”的方式对属性进行赋值,则需要将属性声明为私有的private—>此时针对属性就体现了封装性。

封装性的体现
  我们将类的属性xxx私有化private,同时,提供公共的public方法来获取getXxx和设置setXxxx

拓展:封装性的其他体现:比如 不对外暴露的私有方法、单例模式、如果不希望类在包外被调用,可以将类设置为缺省(类只能是public或缺省)等等。

封装性的体现,需要权限修饰符配合

  1. Java规定的四种权限修饰符:private、缺省、protected、public,置于类成员定义前,用来限定对象对该类成员的访问权限。
    权限修饰符
  2. 四种权限都可以用来修饰类的内部结构:属性、方法、构造器、内部类 (无代码块)
    修饰类的话,只能使用:缺省、public

总结:Java提供了四种权限修饰符来修饰类及类的内部结构,体现了其在被调用时的可见性大小。

2.1.1 类的成员之三(构造器也称构造方法)

构造器的作用:

  1. 创建对象
  2. 初始化对象的信息

说明:

  1. 如果没有显式的定义类的构造器的话,则系统默认提供一个空参的构造器(默认构造器的权限和类权限相同)
  2. 定义构造器的格式:权限修饰符 类名(形参列表){ }
  3. 一个类中定义的多个构造器,彼此之间构成重载
  4. 一旦我们显示的定义了类中的构造器之后,系统就不再提供默认的空参构造器
  5. 一个类中,至少会有一个构造器

总结:属性赋值的先后顺序

① 默认初始化
② 显示初始化/③ 在代码块中赋值 (这两个看写的先后顺序)
④ 构造器中初始化
⑤ 通过“对象.方法” 或 “对象.属性”的方式,赋值

拓展知识:JavaBean

① JavaBean是一种Java语言写成的可重用组件
②所谓JavaBean,符合如下标准的java类:

类是公共的
有一个无参的公共的构造器
有属性,且有对应的get、set方法


在这里插入图片描述
拓展知识:UML类图
在这里插入图片描述

2.2 继承性

1. 继承性的好处

① 减少了代码的冗余,提高了代码的复用性
② 便于功能的扩展
③ 为之后的多态性的使用,提供了前提

2. 继承性的格式:class A extends B{ }

A:子类、派生类、subclass
B:父类、超类、基类、superclass

① 体现:一旦子类A继承父类B之后,子类A中就获取了父类B中声明的所有的属性和方法;
特别的,父类中声明为private的属性或方法,子类中继承之后,仍然认为获取了父类中的私有结构。只是因为封装性的影响,使得子类不能直接调用父类的结构而已。
② 子类继承父类之后,还可以声明自己特有的属性或方法:实现功能的拓展

3. Java中关于继承性的规定

① 一个类可以被多个子类继承
② Java中类的单继承:一个类只能有一个父类
③ 子父类是相对的概念
④ 子类直接继承的父类称为直接父类,间接继承的父类称为间接父类
⑤ 子类继承父类之后,就获取了父类以及所有间接父类中声明的属性和方法
在这里插入图片描述
4. 类图

子类箭头指向父类
在这里插入图片描述

2.2.1 Object类

eclipse中快捷键ctrl+t可以看到类的继承情况

如果我们没有显示的声明一个类的父类的话,则此类继承于java.lang.Object类。也就是说所有java类(除java.lang.Object类之外)都直接或间接的继承于java.lang.Object类。

所以,所有的java类具有java.lang.Object类声明的功能,后面会对Object进行讲解。

2.2.2 方法的重写(override / overwrite)

1. 重写: 子类继承父类之后,可以对父类中同名同参数的方法,进行覆盖操作

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
数字乡村和智慧农业的数字化转型是当前农业发展的新趋势,旨在通过应用数字技术,实现农业全流程的再造和全生命周期的管理服务。中国政府高度重视这一领域的发展,提出“数字中国”和“乡村振兴”战略,以提升国家治理能力,推动城乡融合发展。 数字乡村的建设面临乡村治理、基础设施、产业链条和公共服务等方面的问题,需要分阶段实施《数字乡村发展战略纲要》来解决。农业数字化转型的需求包括满足市民对优质农产品的需求、解决产销对接问题、形成优质优价机制、提高农业劳动力素质、打破信息孤岛、提高农业政策服务的精准度和有效性,以及解决农业融资难的问题。 数字乡村建设的关键在于构建“1+3+4+1”工程,即以新技术、新要素、新商业、新农民、新文化、新农村为核心,推进数据融合,强化农业大数据的汇集功能。数字农业大数据解决方案以农业数字底图和数据资源为基础,通过可视化监管,实现区域农业的全面数字化管理。 数字农业大数据架构基于大数据、区块链、GIS和物联网技术,构建农业大数据中心、农业物联网平台和农村综合服务指挥决策平台三大基础平台。农业大数据中心汇聚各类涉农信息资源和业务数据,支持大数据应用。信息采集系统覆盖市、县、乡、村多级,形成高效的农业大数据信息采集体系。 农业物联网平台包括环境监测系统、视频监控系统、预警预报系统和智能控制系统,通过收集和监测数据,实现对农业环境和生产过程的智能化管理。综合服务指挥决策平台利用数据分析和GIS技术,为农业决策提供支持。 数字乡村建设包括三大服务平台:治理服务平台、民生服务平台和产业服务平台。治理服务平台通过大数据和AI技术,实现乡村治理的数字化;民生服务平台利用互联网技术,提供各类民生服务;产业服务平台融合政企关系,支持农业产业发展。 数字乡村的应用场景广泛,包括农业生产过程、农产品流通、农业管理和农村社会服务。农业生产管理系统利用AIoT技术,实现农业生产的标准化和智能化。农产品智慧流通管理系统和溯源管理系统提高流通效率和产品追溯能力。智慧农业管理通过互联网+农业,提升农业管理的科学性和效率。农村社会服务则通过数字化手段,提高农村地区的公共服务水平。 总体而言,数字乡村和智慧农业的建设,不仅能够提升农业生产效率和管理水平,还能够促进农村地区的社会经济发展,实现城乡融合发展,是推动中国农业现代化的重要途径。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值