《2021春招复习3》Java基础《面向对象》

本文详细介绍了Java反射机制,包括定义、优缺点,对比Class.forName和ClassLoader的区别。此外,阐述了面向对象的三大特性——封装、继承和多态的含义与应用场景。在继承和组合的选择上,强调了组合的灵活性和优势。接着,讨论了重载和重写的区别,以及静态属性和静态方法在继承中的特点。最后,对比了抽象类和接口的差异,指出在设计时如何选择使用。

18.Java反射机制

定义:

(1)Java反射机制的核心是在程序运行时动态加载类并获取类的详细信息,从而操作类或对象的属性和方法。本质是JVM得到class对象之后,再通过class对象进行反编译,从而获取对象的各种信息。

(2)Java属于先编译再运行的语言,程序中对象的类型在编译期就确定下来了,而当程序在运行时可能需要动态加载某些类,这些类因为之前用不到,所以没有被加载到JVM。通过反射,可以在运行时动态地创建对象并调用其属性,不需要提前在编译期知道运行的对象是谁。

优缺点:

1.优点:运行期类型的判断,动态加载类,提高代码灵活度。
2.缺点:(1)性能瓶颈,反射相当于一系列解释操作,通知JVM要做的事情,性能比直接的java代码要慢很多。
(2)反射调用方法时可以忽略权限检查,因此可能会破坏封装性而导致安全问题。

Class.forName和classloader的区别(结合JVM类加载)

Class.forName除了将类的.class文件加载到JVM中之外,还会对类进行解释,执行类中的static块。而classloader只干了一件事情,就是将.class文件加载到JVM中,不会执行static中的内容,只有在newInstance才会去执行static块。forName()得到的class初始化工作已完成。
最重要的区别在于forName会初始化Class,而loadClass不会。因此如果要求加载时,类的静态变量被初始化或者静态块中的代码被执行就只能用forName,而用loadClass只有等创建类实例时才会进行这些初始化。

比较详细的介绍:Java基础篇:反射机制详解

19、简述面向对象的三大特征(封装,继承,多态)

封装:

在面向对象思想中,封装指数据(类成员属性)和对数据的操作(类的方法)捆绑到一起,形成对外界的隐藏,同时对外提供可以操作的接口(供外部访问的类成员)。
封装的意义在于保护或者防止代码被我们无意破坏,保护成员属性,不让类以外的程序直接访问或修改,隐藏方法细节。

继承:

继承是从已有的类中派生出一个新的类,新的类能吸收已有类的数据属性和行为,并能扩展新的能力。
为什么要继承:反应现实的真实关系,减少代码冗余,对父类的属性和方法进行扩展和重写。继承中,子类不可以选择性的继承父类的关系而是全部继承父类的属性和方法,其中父类又叫超类和基类,子类又叫派生类。父类是子类的具体化。java不支持父类的多继承,多继承是通过接口实现的。

多态:父类引用指向不同子类对象。

Java实现多态有三个必要的条件:继承,重写,向上转型。

  1. 继承:在多态中必须存在有继承关系的子类和父类。
  2. 重写:子类对父类中某些方法进行重新定义,在调用这些方法时就会调用子类的方法。
  3. 向上转型:在多态中需要将子类的引用赋给父类对象,只有这样该引用才能够调用父类的方法和子类的方法。
    实现方式:接口多态性,继承多态性,抽象类实现的多态性。
    实现原理:动态绑定。

20、简述继承和组合的区别和选择

类继承和对象组合是代码复用的两种最常用的技术。

继承

继承是is-a的关系,比如说Student继承Person,那么student is a Person。继承的优点是子类可以重写父类的方法来方便地实现对父类的扩展。

继承的优点:

  1. 大部分代码继承,提高了代码复用率,并且容易进行新的实现。
  2. 可以通过重写父类方法来扩展父类。

缺点:

  1. 父类的内部细节对子类可见的;
  2. 子类从父类继承的方法在编译时就确定下来了,所以无法在运行期间改变从父类继承的方法。
  3. 子类与父类是高耦合,违背了面向对象思想。若对父类方法做修改如增加了一个参数,则子类方法必须做出相应的修改。

组合

组合是has-a关系,组合就是设计类的时候把要组合的类的对象加入到该类中作为自己的成员变量。

优点:

  1. 当前对象只能通过所包含的那个对象去调用其方法,所以所包含的对象的内部细节对当前对象不可见。

  2. 组合的对象间低耦合。如果修改包含对象的类中代码不需要修改当前对象类的代码。

  3. 当前对象可以在运行时动态绑定所包含的对象。可以通过set方法给所包含对象赋值。

缺点:

  1. 容易产生过多对象。
  2. 为了能组合多个对象必须仔细对接口进行定义。

组合和继承如何选择

组合比继承更具灵活性和稳定性,所以设计的时候优先使用组合。只有当下列条件满足时才考虑使用继承:

  1. 子类是一种特殊类型(String类,Object类,包装类);而不只是父类的一个角色。
  2. 子类的实例不需要变成另一个类的对象。
  3. 子类是父类的扩展。

为什么优先选择组合

扩展性:继承是静态复用,在编译后子类和父类的关系的关系就已经确定了。组合是动态复用,它们之间的关系是在运行时候才确定的,即在对对象没有创建运行前,整体类是不会知道自己将持有特定接口下的那个实现类。在扩展方面组合比继承更具广泛性。

单一性:继承中父类定义了子类的部分实现,而子类又会重写这些实现,修改父类的实现,在设计模式中认为

这是一种破坏了父类的封装性的表现。这个结构导致的结果是父类实现的任何变化,必然导致子类的改变。然而组合不会出现这种情况。对象的组合就是有助于保持每个类被封装,并被集中在单个任务上(符合类设计的单一原则)。这样类的层次不会扩大,一般不会出现不可控的庞然大类。而类的继承就可能出现这种问题。一般编码规范都要求类的层次结构不要超过3层,组合是大型系统软件实现即插即用时的首选方式。

按需选择:"优先使用对象组合,而不是继承"是面向对象设计的第二原则。但是只是优先,而并非一定,这还得视情况而定。

21、Java 中重载与重写的区别

Java 三大特性:封装,继承,多态。

多态:

重载:

同一类中同名函数,具有不同参数个数或类型(返回值不参与),是一个类中多态性的体现。是由静态类型确定,在类加载的时候就确定,属于静态分类。

重写:

子类中含有与父类相同的名字、返回类型和参数表,则是重写,实在继承中多态的表现,属于动态分类。

区别:

方法的重载和重写都是实现多态的方式,区别在于前者实现的是编译时的多态性,而后者实现的是运行时的多态性。

重载发生在一个类中,同名的方法如果有不同的参数列表,则视为重载。重载对返回类型没有特殊的要求,不能根据返回类型进行区分。

重写发生在子类和父类之间,重写要求子类重写方法和父类被重写方法有相同的参数列表,有兼容的返回类型,比父类被重写方法更好访问,不能比父类被重写的方法声明更多的异常(里氏代换原则)。

构造器可以被重写吗?

构造器不能被继承,所以不能被重写Override,但可以被重载Overload(不同参数即可)。若父类有参数的构造器,则子类必须用super调用并加上相应参数,若父类有无参构造器,子类不用super,系统自动调用无参构造器。(隐藏了super())

22、Java中静态属性和静态方法可以被继承吗?

可以被继承,但是不能被重写,而是隐藏,只有非静态的方法可以被继承和重写。

表面原因:

  1. 静态方法和属性是属于类的,调用的时候直接通过类名.方法名完成对,不需要继承机制即可被调用。如果子类里定义了静态方法和属性,那么父类的静态方法和属性称之为“隐藏”。如果想要调用父类的静态方法和属性,直接通过父类名.方法或变量名完成,至于是否继承一说,子类可以继承静态方法和属性,但是跟非静态方法和属性不太一样,存在隐藏这种情况。
  2. 静态属性和静态方法都可以被继承和隐藏而不能被重写,因此不能实现多态(父类引用指向不同的子类对象)。非静态方法可以被继承和重写,可以实现多态。

深入原因:

静态方法和属性是按“编译时期的类型”进行调用的,而不是按“运行时期的类型”进行调用,的,而非static方法,才是按“运行时期的类型”进行调用的。

JVM中的非虚方法和实方法的理解:

1、非虚方法

(1)如果方法在编译期确定了具体的调用版本,这个版本在运行时不可变

(2)静态方法,私有方法,final方法,实例构造器,父类方法都是非虚方法

2、虚方法

不是非虚方法的都是虚方法

3、虚拟机提供了以下方法调用指令

(1)普通调用指令

i)invokestatic:调用静态方法,解析阶段确定唯一方法

ii)invokespecial:调用方法,私有及父类方法,解析阶段确定唯一方法

iii)invokevirtual:调用所有虚方法

iv)invokeinterface:调用接口方法

(2)动态调用指令

invokedynamic:动态解析需要调用的方法,然后执行上述普通调用指令固化在虚拟机内部,方法的调用执行不可人为干预

但是invokedynamic则支持由用户确定方法

注意:

(1)invokestatic和invokespecial 调用的方法都是非虚方法

(2)invokevirtual和invokeinterface调用的方法都是虚方法(排除方法签名中带final)

(3)invokedynamic指令在jdk7需要借助工具才可以查看到该字节码,在jdk8,使用Lambda表达式后,在字节码上会有invokedynamic指令的体现。

23.抽象类和接口的区别:

1.抽象类:(为了继承而存在)

(1)抽象方法必须为public或者protected(因为如果为private,则不能被子类继承,子类便无法实现该方法),默认为public。

(2)抽象类不能用来创建对象;

(3)如果一个类继承于一个抽象类,则子类 必须实现父类的抽象方法。如果子类没有实现父类的抽象方法,则必须将子类也定义为abstract类。

2.接口:(更加抽象)

(1) 访问修饰符:只能是public 或者默认
(2) extends:接口支持多继承
(3) 接口中的属性只能是常量,默认就是public static finnal
(4) 接口中的方法默认是public abstract

要点:

1、接口不能实例化对象 可以用来声明引用变量的类型
2、一个类实现一个接口,那么必须实现这个接口中定义的所有方法,并且只能是public
3、jdk1.7以及之前 接口中只能有方法的定义 ,jdk1.8之后可以有default(虚拟扩展方法)和静态方法

接口和抽象类的区别

接口 抽象类

  1. 不考虑java8中default方法的情况下,接口中是没有实现代码的实现;抽象类中可以有普通成员方法 ,并且可以定义变量。

  2. 接口中的方法修饰符号只能是public,抽象类中的抽象方法可以有public protected default。

  3. 接口中没有构造方法,抽象类中可以有构造方法。

3.语法层面:

(1)抽象类可以提供成员方法的实现细节,而接口中只能存在public abstract方法。

(2) 抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是public static final类型的

(3) 接口中不能含有静态代码块和静态方法,而抽象类可以有静态代码块和静态方法。

(4) 一个类只能继承一个抽象类,却可以继承多个接口。

设计层面:

(5)类是“是不是关系”,接口是“有没有关系”。

抽象类作为很多子类的父类,它是一种模板式设计。而接口是一种行为规范,它是一种辐射式设计。

4.接口和抽象类如何选择:

1、当我们需要一组规范的方法的时候,我们就可以用接口,在具体的业务中,来对接口进行实现,能达到以不变应对万变,多变的需求的情况我们只需要改变对应的实现类 。
2、如果多个实现类中有者相同可以复用的代码 这个时候就可以在实现类和接口之间,添加一个抽象类,把公共的代码抽出在抽象类中。然后要求不同实现过程的 子类可以重写抽象类中的方法,来完成各自的业务。

C语言-光伏MPPT算法:电导增量法扰动观察法+自动全局搜索Plecs最大功率跟踪算法仿真内容概要:本文档主要介绍了一种基于C语言实现的光伏最大功率点跟踪(MPPT)算法,结合电导增量法与扰动观察法,并引入自动全局搜索策略,利用Plecs仿真工具对算法进行建模与仿真验证。文档重点阐述了两种经典MPPT算法的原理、优缺点及其在不同光照和温度条件下的动态响应特性,同时提出一种改进的复合控制策略以提升系统在复杂环境下的跟踪精度与稳定性。通过仿真结果对比分析,验证了所提方法在快速性和准确性方面的优势,适用于光伏发电系统的高效能量转换控制。; 适合人群:具备一定C语言编程基础和电力电子知识背景,从事光伏系统开发、嵌入式控制或新能源技术研发的工程师及高校研究人员;工作限1-3的初级至中级研发人员尤为适合。; 使用场景及目标:①掌握电导增量法与扰动观察法在实际光伏系统中的实现机制与切换逻辑;②学习如何在Plecs中搭建MPPT控制系统仿真模型;③实现自动全局搜索以避免传统算法陷入局部峰值问题,提升复杂工况下的最大功率追踪效率;④为光伏逆变器或太阳能充电控制器的算法开发提供技术参考与实现范例。; 阅读建议:建议读者结合文中提供的C语言算法逻辑与Plecs仿真模型同步学习,重点关注算法判断条件、步长调节策略及仿真参数设置。在理解基本原理的基础上,可通过修改光照强度、温度变化曲线等外部扰动因素,进一步测试算法鲁棒性,并尝试将其移植到实际嵌入式平台进行实验验证。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值