java特征
一:封装
基本概念
~通常情况下测试类中可以对类中的成员变量进行访问(进行赋值),若赋值的数据合法但不合理时(比如卖家将自己售卖的商品价格定为一个负数时),这个时候编译和运行都不会出错,但是输入的数据与现实不符。
为了避免上述的错误发生,就需要对成员变量进行密封包装处理,这种密封包装成员变量的机制我们称它为封装,换句话也就是说封装是一种保证成员变量合理性的一种机制。
封装的作用
保证类中成员变量的合理性
封装的具体实现(三步走)
第一步:私有化成员变量,使用private关键字修饰
第二步:设置共有的(public修饰的)set方法,并在set方法方法体中进行合理的判断
第三步:在构造体中通过建立合理值判断的set方法对成员变量进行赋值
~所以封装也就是要堵死一切可能让类中成员变量出错的方式,无非就是直接调用和set方法,还有构造方法。
~在set方法中我们一般进行合理值的判断,而在含参构造方法中我们一般通过调用加了合理值判断的set方法进行成员变量的赋值(因为在实际编程中,我们一般不希望有太多的重复的代码)
~只要提到封装就进行三步走
二:继承
基本概念
都有相同的特种和行为时,我们可以将这些类中相同的内容提取出来组成公共类,让多个类吸收公共类中的已有特征和行为,而这多各类只需要编写自己独有的特征和行为的方式就叫做继承
~继承就是子类继承父类的公共特征,再编写子类自己特有的属性和方法
~使用继承可以提高代码的复用性,扩展性,可维护性
扩展性:也就是继承本身,也就是扩大。
复用性:重复使用
在java语言中使用extends(扩展)关键字来表示继承
使用继承时的注意事项
1.子类可以继承父类的成员变量和成员方法,其中私有成员变量可以继承但不能直接使用,子类不可以继承父类的私有成员变量和构造方法。(原因:一:子类不能继承父类的构造方法,因为构造方法要与类名想同,而子类和父类的类名显然不同,所以子类也就不继承父类的构造方法。二:私有成员按理来说是不可以被继承的,但是有一个例外就是私有成员变量可以被继承,所以这里的成员变量不是特例也就自然不能被继承,而且私有方法继承下来也没有用,因为子类如果继承了父类的私有方法的话那么开始时私有的成员方法是在父类中被定义的,所以现在的子类也算做类外,自然就不能使用,所以也就干脆不能继承,而刚刚说过,私有成员变量是一个特例)
~私有成员(成员=变量+方法)按理说都不能继承,但是这里的私有成员变量是一个特例,可以被继承,但是私有成员方法就不嗯能够被继承。
2.无论使用何种方式构建子类对象,子类都会自动调用父类的无参构造方法,就相当于在子类被调用的构造方法的第一句加上super();的效果
~其实也就是在子类在构造对象时编译器会自动在被调用的子类构造方法的第一句加上super();
(所以如果我们在调用子类的构造方法构造对象时,如果父类之中我们只定义了有参构造而没有定义无参构造方法,那么这个时候编译器就会报错)
在我们日常编译中我们以后应该在使用继承时,在子类的无参构造方法中的第一行调用父类的无参构造方法,在子类的有参构造方法的第一行调用父类的有参构造方法(标准且降低了代码的重复性)
(也就是在子类的无参构造方法的第一句加上super();在子类的含参构造方法的第一句加上 super(name,age),这里的name和age都是举例,实际中这两个都是实参)
this()和super()不能同时出现在同一个构造方法中,因为this()和super()调用构造方法时都要在构造方法中第一行语句,而只能有一个第一行,也就自然不能同时出现
3.使用继承必须满足子类is a父类的逻辑关系(即不能乱用继承)
4.java语言只支持单继承而不支持多继承,也就是一个子类只有一个父类,而一个父类可以有多个子类。
特征三:多态
基本概念
多态主要指同一种事物表现出来的多种形态。
多态的语法格式
父亲类型 引用变量名 = new 子类类型构造方法
多态的效果
1.当父类的引用指向子类的对象时,父类的引用可以直接调用父类独有的方法。
2.当父类的引用指向子类的对象时,父类的引用不能直接调用子类的独有方法。(要通过强制类型转换向下转型后再调用)
3.对于父类,子类都有的非静态方法来讲,编译时调用的是父类的非静态方法,而在运行时调用的是子类的非静态方法。
4.对于父类,子类都有的静态方法来讲,编译时和运行时都调用的时父类的静态方法。
-
成员变量(包括非静态和静态的变量)编译和运行都是看左边
-
非静态的成员方法编译看左边,运行看右边。
-
静态的成员方法编译和运行都是看左边。
例:Person p=new Student();
注意:这里的p是当做父类来用的,而不是当做子类来用的
所以就有:
1.p只能调用父类独有的属性和方法。
2.p不能直接调用子类中独有的属性和方法。
3.如果子类中重写了父类的方法,非静态方法调用的是子类的(编译时调用的是父类的,但在运行阶段调用的还是子类的),静态方法是调用的父类的(编译时和运行时都调用父类的)