1 继承
继承的概念
继承也叫传承,也就是自上而下的传递;当我们在描述某些事物的时候 发现 有些事物具有重复的属性和行为,那么 就可以将这些重复的东西进行抽取 组合成一个新的类别,这个新的类别称之为父类。
通过extends关键字可以实现类与类的继承:
class子类名 extends 父类名{ }
继承的好处和弊端
- 提高了代码的复用性:多个相同的成员可以方法放到同一个类中;
- 提高了代码的为属性:如果功能的代码需要修改,修改一处即可;
- 让类与类之间产生了关系,是多态的前提:其实这也是继承的一个弊端,类的耦合性很强;
- 开发原则:低耦合,高内聚
- 耦合:类与类的关系;
- 内聚:就是自己完成某件事情的能力。
注意
- 和传统的理解不同,子类并不是父类的一个子集。实际上,一个子类通常比它的父类包含更多的信息和方法。
- 父类中的私有数据域在该类之外是不可访问的。因此,不能在子类中直接使用。但是,如果父类中定义了公共的访问器 / 修改器,那么可以通过这些公共的访问器 / 修改器来访问和修改它们。
- 不是所有的 “是一种”(isa) 关系都该用继承来建模。例如:正方形是一种矩形,但是不应该定义一个 Square 类来扩展 Rectangle 类,因为 width 和 height 属性并不适合于正方形。应该定义一个继承自 CeometricObject 类的 Square 类,并为正方形的边定义一个 side 属性。
- 继承是用来为 “是一种” 关系( isa) 建模的。不要仅仅为了重用方法这个原因而盲目地扩展一个类。例如:尽管 Person 类和 Tree 类可以共享类似高度和重量这样的通用特性,但是从 Person 类扩展出 Tree 类是毫无意义的。一个父类和它的子类之间必须存在 “是一种”(is a) 关系。
- 某些程序设计语言是允许从几个类派生出一个子类的。这种能力称为多重继承。但是在 Java 中是不允许多重继承的。一个 Java 类只可能直接继承自一个父类。这种限制称为单一继承( single inheritance)。如果使用 extends 关键字来定义一个子类,它只允许有一个父类。然而,多重继承是可以通过接口来实现的。
super关键字
关键字 super 是指这个super 关键字所在的类的父类。关键字 super 可以用于两种途径:
- 调用父类的构造方法。
- 调用父类的方法。
调用父类的构造方法
调用父类构造方法的语法是:super()或者super(parameters);语句 super 调用父类的无参构造方法,而语句 super(arguments) 调用与参数匹配的父类的构造方法。语句 super 和 super (arguments) 必须出现在子类构造方法的第一行,这是显式调用父类构造方法的唯一方式。
继承中成员变量的特点
继承中成员变量和父类变量重名的情况下:先找局部再找对象最后找父类
继承中成员变量和父类变量不重名的情况下:局部找完之后找对象再找子类静态最后找父类静态
继承中构造函数的特点
子类中所有的构造函数默认都会访问父类中的无参构造函数;因为子类会继承父类中的数据;可能还会使用父类中的数据;所以子类在初始化之前,一定要完成父类的初始化。
重写
子类中出现了和父类一模一样的方法声明,也被称为方法覆盖。
注意:
- 方法重写发生在通过继承而相关的不同类中;方法重载可以发生在同一个类中,也可以发生在由于继承而相关的不同类中。
- 方法重写具有同样的签名和返回值类型;方法重载具有同样的名字,但是不同的参数列表。
重写与重载的区别
重载是指同类中函数名相同, 参数列表不同;而函数的重写是指在子父类中的函数定义全部一样。
多态
概念
事物的多种形态;一个事物具有多种形态,在不同的场合不同的地点具有不同的形态,但是本质不变。
在代码中指子类对象指向父类的引用:
父类.变量名=new 子类()
Animal a =new Dog();
多态的特点
成员变量在多态中的特点:只能访问父类中的变量
成员函数在多态中的特点:如果存在重写,则调用重写,没有重写,则调用父类成员函数,都没有则报错;但是子类的特有行为不能调用。
静态变量在多态中的特点:只能访问父类中的静态变量。
静态函数在多态中的特点:只能访问父类中的静态函数,所以间接证明了,静态函数不存在重写。
class Fu{ static int num=20; void show(){ System.out.println("Fu show..."); } static void haha(){ System.out.println("Fu staic haha..."); } } class Zi extends Fu{ void show(){ System.out.println("Zi show..."); } static void haha(){ System.out.println("Zi staic haha..."); } }
抽象类
- 抽象:模糊不定,不确定,不明白,不清晰
- 抽象函数:从代码上而言 只有函数的声明但是没有函数体当描述一类事物的时候,发现每个事物都有相同的功能,但是具体执行却不一样
那么在对这些事物进行父类抽取的时候,仅仅保留该功能的声明,而无需写出函数体,此时,这个函数就是抽象函数,该函数的具体执行由子类决定。
抽象类:拥有抽象函数的类就是抽象类(但是抽象类不一定有抽象函数)。
abstract class Living{ public abstract void eat(); public void sleep(){ System.out.println("睡觉....."); } } class Dog extends Living{ public void eat(){ System.out.println("狗吃骨头"); } } class Cat extends Living{ //重写 实现 public void eat(){ System.out.println("猫吃鱼"); } }
抽象类的特点
1.抽象类有无构造函数,因为抽象类一般而言是作为父类存在的子类在创建对象是,服父类肯定会为其进行一些初始化所以抽象类肯定有构造函数!
2.抽象类不能否创建对象,因为就算抽象类能创建出对象,但是其函数没有具体的执行,是不确定的而且对象本身就是一个确定的东西,所以冲突。
3.抽象类和一般类有何区别?
唯一区别就在于抽象类有抽象函数
其余一律和一般类相同!
4.抽象函数不能和那些关键字共存
final 修饰函数 表示该函数并不能被重写
final 修饰类 表示该类不能被继承
private
static 静态不存在重写的概念 静态必须是一个具体的事物
接口 :interface
从代码上而言:就是一种特殊的抽象类;当一个抽象类中,所有的函数都是抽象的,则可以用接口去表示,那么在接口中属性就表示:常量;行为:抽象函数。
接口的用处
- 解耦:表示向外界提供一套统一的标准
- 传参:传递一段代码
Button bt_pay=new Button(); //匿名实现子类的匿名对象 bt_pay.doSomething(new Task(){ public void doWhat(){ System.out.println("支付..."); } });
- 对事物功能的拓展
// 表现了对事物功能的拓展 abstract class Animal{ public abstract void eat(); } class Person extends Animal implements A,B{ public void eat(){ System.out.println("人啥都吃"); } public void daoMang(){ System.out.println("导盲人"); } public void maiMeng(){ System.out.println("卖萌人"); } interface A{ void daoMang(); } interface B{ void maiMeng(); }
接口与接口之间有多继承的关系
因为一个子类的父类1与父类2之间,纵使有同名函数,但是有不同函数体,所以不知道具体该执行哪一个?
但是一个子类的接口1与接口2之间,纵使有同名函数,但是没有执行体,执行体由子类自行决定。
interface A{ void showA(); void show(); } interface B{ void showB(); void show(); } interface C extends A,B{ void showC(); void show(); } class Demo implements C{ public void showA(){} public void showB(){} public void showC(){} public void show(){ } }
单例模式
单例模式:该类只能创建一个对象
单线程环境下的单例模式
1.外界不能直接创建对象-构造函数私有化
2.对象在在内部创建 new Single();
3.该对象最终要提供出去,外界不能直接访问吗?所以get最好
4.get不能为成员函数!所以是static
5.必须保证类的内部,new只执行一次 static
//饿汉式 class Single{ private static Single s=new Single(); private Single(){ } public static Single getInstance(){ return s; } }
//饱汉式 class Single2{ private static Single2 s=null; private Single2(){ } public static Single2 getInstance(){ if(s==null){ s=new Single2(); } return s; } }
代理模式
为什么能代理呢?因为他们本身是同一种事物所以可以进行代理。
来源:51CTO
作者:Soul的人生
链接:https://blog.csdn.net/weixin_44575563/article/details/87871175