什么是多态,多态的成员访问特点
多态:一个事物在不同时刻体现的不同形态(内存中的变化)
前提条件
1)存在继承关系
2)存在方法重写
3)父类引用指向子类对象 Fu fu = new Zi() ;
多态的成员访问特点:
成员变量: 编译看左,运行看左!
成员方法:编译看左,运行看右,由于存在方法重写,子类的功能将父类的功能覆盖了!
静态的方法:算不上方法重写,编译看左,运行看左: static修饰的都是和类相关的
2.多态的好处有哪些以及弊端
好处:
1)提高了代码的复用性(由继承保证)
2)提高了代码的扩展性(由多态保证)
//有动物类Animal
继承关系
有猫类Cat
有狗类Dog
//Java23设计模式 :创建型设计模式 结构型设计模式 行为型设计模式
class AnimalFactory{ //动物工厂 ----> 静态工厂模式
private AnimalFactory(){}
//创建很多个动物
public static Cat creatCat(){
Cat c = new Cat() ;
return c ;
//return new Cat() ;
}
public static Dog creatDog(){
return new Dog() ;
}
//优化
public static Animal createAnimal(String type){
if("dog".equals(type)){
return new Dog() ;
}else if("cat".equals(type)){
return new Cat() ;
}else{
System.out.println("对不起,此工厂不提供这个动物的创建") ;
}
}
}
//测试
Animal a = AnimalFactory.createAnimal("dog") ; //Animal a = new Dog() ; 多态的应用
传统方式---> 不好优化
Cat c = new Cat() ;
Dog d = new Dog() ;
Animal a = new XXX() ;
3.什么是抽象类?抽象类的本质是什么
抽象类:
一个事物如果存在抽象功能,那么这个类一定是抽象类!
抽象类:在真实事物中,它是一个泛指(概括性的事物,非具体事物) abstract 修饰
抽象类中不一定有抽象方法,也可以是非抽象方法!
抽象类的本质:强制子类必须完成的事情(要将抽象类中的所有的抽象方法必须重写!)
4.封装,继承,多态是什么?
封装:
将一个事物的属性私有化,保证其数据的安全性(隐藏),对外提供公共访问方法操作!
开发中:
1)定义这个类--- 实体类 User类 ,Order订单类,Product商品类...
2)需要封装这个类:获取数据
类名 对象 = new 类名() ;
有参构造方法/setXXX(xx):赋值 :形式参数----->数据库中查询到
User user = new User() ;
user.setUserName("zhangsan") ;
继承:
将多个事物的共有属性抽取出来,在一个独立类中定义,然后独立的类和这些产生一个关系: extends
目前---->学习继承---Object :以及Java高级部分----->jdk提供类,核心接口----之间就会继承体现!
开发中:
1) 用户类 ---- > 数据库: user表
用户名称
用户名密码
2) 订单类: -----> 数据库:order表
订单编号:orderId
订单小计金额:subtotal
针对多表之间查询:
查询订单信息的同时查询出 订单属于哪个用户的
订单类中并没有用户的信息
单独定义一个类:OrderUser extends Order
用户名称
用户名密码
多态:
一个事物在不同时刻体现的不同形态(内存中的变化)
开发中:提高代码的扩展性
Fu f = new Zi() ; //Fu类:具体类----> 具体类多态
Fu f = new Zi() ; //Fu类:抽象类----> 抽象类多态(其次)
接口类型 对象名 = new 接口的子实现类() ; ---->接口多态 (使用居多)
后期:压根项目中就见不到new 关键字----全部都是通过底层(反射技术---(内省))创建该类对象:
5.static关键字的特点
1)随着的加载而加载,加载一次,被静态修饰的先进内存
2)优先于对象存在 :不能和this共存
3)可以被多个对象共享,共用
4)可以被类名直接访问
类名.方法名();
类名.变量名 ;
抽象类和接口的区别?
1)成员的区别
成员变量:
抽象类:可以是变量,也可以常量(使用final关键字)
接口:只能是常量:存在默认修饰符:public static final(可以省略不写)
构造方法
抽象类: 有构造方法;无参/有参: 针对父类进行分层初始化
抽象类多态的形式: 抽象的父类名 对象名 = new 子类名() ;
接口:没有构造方法
成员方法:
抽象类:既可以是抽象方法(必须携带abstract),也可以是非抽象方法
接口:只能是抽象方法:存在默认修饰符:public abstract
2)关系的区别
类与类,类与接口,接口与接口之间的关系
类与类之间:继承的关系 extends :支持单继承,不支持多继承,可以多层继承
类与接口之间:实现关系 implements:
一个类继承另一个类的同时,可以实现多个接口
接口与接口之间:继承关系 extends :可以单继承,也可以多继承
interface 接口名1 extends 父接口1,父接口2,...{}
3)设计理念的区别
抽象类----体现的继承关系(类与类之间的关系居多),---描述 "is a"的关系
接口--- 实现关系:一个事物所具备的额外功能,---描述的是一种"like a"的关系
使用接口----使用接口多态---可以提高代码的扩展性!
一个类,没有抽象方法,可不可以将这个类定义为抽象类呢? 意义是什么?
* 可以定位抽象类,意义:就是为了这个类不能够实例化!
*
* 一般情况:如果一个类中,没由抽象方法,将它定义为抽象类
* 它的实例化: 可以通过它里面的静态功能,静态功能的返回值类型是当前类本身!
* 后期:Calendar:日历类 java.util.Calendar;
*
* Calendar:抽象类
* public static Calendar getInstantce(){
*
* ....
* ....
* ....
* return new GregorianCalendar() ; Calendar的子类
* }
*
* 抽象 的关键字:
* abstract不能和哪些关键字使用(冲突)
*
*
* abstract可以修饰类,才是这个类不能实例化了,这个类叫抽象类
*
* abstract可以修饰方法----抽象方法:没有方法体
*
* 和private关键字不能一块使用:被private修饰的只能在本类中访问,外界类中的成员不能访问!
* 和static关键字冲突:如果加了静态,子类要重写父类的方法,这种访问方式: 多态:Fu f = new Zi() ;f.方法名() ;
* 静态的方式--->随着类的加载而加载: 类名.方法名();
* 和final关键字冲突:被final修饰的方法不能被重写,而abstract抽象方法,要强制子类必须重写,否则子类报错,出现冲突了!
*
*
* abstract:和默认修饰符 abstract 返回值类型 方法名(形参列表) ;
* 和public可以使用
* 和protected:
* 限定的是子类: 在同一个包下/或者在不同包下 都可以访问
方法重写的注意事项:
* 子类继承父类,要重写父类的功能的时候,必须要保证子类的方法的访问权限足够大,要么
* 就父类的权限保持一致即可!
什么是接口?
* 接口是比抽象类还抽象的事物,它体现的一种 "扩展性"--- 事物的额外功能!
* 如果一些具体事物能够将额外功能实现了,那么这些具体事物就应该具备这些功能了!
* 接口:体现的是一种 "like a"的关系
* 跳高猫--->类似猫
*
* 定义格式:
* interface 接口名{ //接口名要见名知意---符号"标识符的规则"
*
* }
* 接口中的方法:只能是抽象方法
* 接口特点:不能实例化:不能new
*
* 将接口的子类称为"子实现类"
* 可以是抽象类, 一定会有抽象类的具体的子类,否则没有意义!
* 也可以是具体类 : 通过具体类实例化
* 接口名 对象名 = new 子实现类名() ;
*
* 子实现类和接口之间的关系:实现关系 :implements
*
* class 子实现类名 implements 接口名{
*
* }
接口的成员特点
*
* 成员变量:只能是常量:存在默认修饰符:public static final ... :可以省略不写
* 构造方法:无
* 成员方法:只能是抽象方法:存在默认修饰符:public abstract :可以省略不写
*
* 开发中,定义了一个接口
* 子实现类名都是在接口名的后面加上Impl
抽象类和接口的区别
1)成员的区别
成员变量:抽象类中可以是常量,也可以是变量
接口:只能是常量:存在默认修饰符 public static final
构造方法:抽象类:存在构造方法,无参/有参-----由于有继承关系,父类先初始化,子类在初始化
接口:没有构造方法
成员方法:抽象类中,既可以是抽象方法,也可以是非抽象方法
接口:只能是抽象方法,存在默认的修饰符:public abstract
形式参数问题研究
* 基本数据类型, 实际参数传递的是当前这个数据值!
* 引用数据类型
*
* 数组:需要传递数组对象
* 类: 具体类:传递的当前类的对象
2)关系区别:
类与类(类:具体类/ 抽象类):都是继承关系:extends,而且只支持单继承,不支持多继承,可以多层继承!
类与接口的关系:(类:具体类/抽象类---具体的子类):实现关系: implements
一个类继承另一个类的同时,可以实现多个接口
接口与接口的关系:继承关系: extends 可以单继承,也可以多继承!(也可以多层继承)
3)设计理念的区别:
抽象类:由于存在继承关系,继承关系体现的是一种"is a"的关系---->A类是B类的一种,或者B类是A类的一种
接口: 描述某个事物本身不具备的额外功能---->扩展功能,体现的一种"like a"的关系,A类类似于B类
猫狗案例+接口+多态
猫和狗:一部分具备跳高的功能---JumpCat/JumpDog
2.如果方法的形式参数是一个数组类型,实际参数应该传递什么?
public void printArray(int[] arr){ //实际参数应该传递的是当前数组对象!
...
}
3.什么是接口,接口的定义格式以及接口和类之间的关系,请代码列举
描述某个事物本身不具备的额外功能---->扩展功能,体现的一种"like a"的关系
interface 接口名{}
class 接口的子实现类名 implements 接口名{}
interface Love{
public abstract void love() ;
}
class LoveImpl implements Love{
public void love(){
System.out.println("爱生活,爱Java,爱高圆圆...") ;
}
}
4.多态的成员特点以及多态的好处
格式:Fu fu = new Zi() ;
成员变量:编译看左,运行看左
成员方法:编译看左,运行看右
构造方法:分层初始化;new Zi()----->
先执行父类的构造方法----父类初始化完毕,然后执行子类构造方法,完成子类的初始化操作
多态的好处:
1)提高代码复用性(继承来保证)
2)提高代码的扩展性(多态完成) 接口多态/抽象类多态
5.this和super的区别
this:代表的本类(当前类)对象的地址值引用
this.变量; 本类的成员变量
this.方法名(); 本类的成员方法
this();本类的无参构造方法
this(xx);本类的有参构造方法
super:代表父类的空间标识(父类的对象地址值引用)
super.变量; 父类的成员变量
super.方法名(); 父类的成员方法
super();父类的无参构造方法
super(xx);父类的有参构造方法
6.abstract和哪些关键字冲突,为什么
abstract关键字:可以修饰类,可以修饰方法(抽象方法)----使用居多
private :本private修饰的只能在本类访问方法,外界类不能访问
static: static随着类的加载而加载,而当前抽象方法需要被子类重写,通过对象名访问的,static又优先于对象存在
final: 被final修饰的方法不能被重写,而抽象方法需要被子类重写,就冲突了
public:公共的:可以使用的
protected:受保护的:可以使用的
同一个包下的
当前类中可以访问
同一个包下的
子类
不同包下的
子类
默认修饰符:可以默认使用
方法的形式参数引用类型:
* 如果是接口类型,如何传递呢?
*
* 那么调用该方法,实际参数需要传递的是当前接口的子实现类对象!
* 通过接口多态来进行实例化!
interface Love{
void love() ;
}
//定义一个类LoveDemo
class LoveDemo{
public void function(Love l){//形式参数是引用类型, 接口类型---实际参数需要传递这个接口的子实现类对象
//接口多态:Love l = new LoveImpl() ;
l.love() ;
}
}
//定义接口的子实现类
class LoveImpl implements Love{
@Override
public void love() {
System.out.println("love Java...") ;
}
}
//测试类
public class ArgsDemo3 {
public static void main(String[] args) {
//要访问LoveDemo类中的function方法,如何访问?
//创建LoveDemo类的对象
LoveDemo ld = new LoveDemo() ;
//Love love= new Love() ;接口不能实例化
//接口多态
Love love = new LoveImpl() ;
ld.function(love);
}
}
方法的形式参数引用类型:
* 如果是抽象类型,如何传递呢?
* 调用该方法,实际参数需要传递的是当前抽象类的子类对象! (抽象类多态)
abstract class Person{
//定义一个抽象方法
public abstract void work() ;
}
//定义PersonDemo类
class PersonDemo{
public void show(Person p){ //形式参数引用类型:抽象类 Person person = new 子类名() ;
p.work();
}
}
//需要提供抽象类的子类:具体类
class Worker extends Person{
@Override
public void work() {
System.out.println("爱生活,爱工作,爱Java...");
}
}
//测试类
public class ArgsDemo2 {
public static void main(String[] args) {
//要访问PersonDemo类中的show方法?
//创建PersonDemo类的对象
PersonDemo pd = new PersonDemo() ;
// Person p = new Person() ;抽象类不能实例化
//抽象类多态
Person p = new Worker() ; //父类引用指向子类对象
pd.show(p) ;
System.out.println("---------------------");
pd.show(new Worker()); //匿名对象
}
}
本文详细介绍了Java中的多态性,包括成员变量和方法的访问特点,以及多态带来的代码复用性和扩展性提升。同时,阐述了抽象类的概念,强调其强制子类完成抽象方法的特点。此外,探讨了接口的使用,作为实现多态的另一种方式,以及接口与抽象类在设计理念上的差异。最后,提到了静态关键字的特性以及在实际编程中的应用。
361

被折叠的 条评论
为什么被折叠?



