软件设计六大原则 :
*
* 1 单一职责原则 : 功能单一,之拥抱一种变化
* 一个方法只负责一件事,这样该方法进行改动的时候,不会影响其他程序,几乎所有程序员都在遵循这个原则
* 优点 : 降低类之间的耦合度,提高可读性,增加可维护性和可扩展性,降低可变性的风险
*
* 2 里氏替换原则 : 所有可以使用父类的地方,一定可以使用子类
*
* 3 依赖倒置原则 : 高层通过抽象依赖底层,细节应该依赖于抽象
*
* 4 接口隔离原则 :
*
* 5 迪米特原则 : 也称为最少知识原则
* 一个类尽量减少自己对其他类的依赖,原则就是低耦合,高内聚
*
* 6 开闭原则 : 对修改关闭,对扩展开放
*
* 变量声明 : 数据类型 变量名 = 值;
*
* 多态 : 父类引用指向子类对象
* 父类引用 : 使用父类声明的引用类型变量
* 指向 : 就是通过这个变量可以找到谁
* 使用父类声明的变量,可以找到子类对象
* Animal a = new Animal();
* Animal a = new Cat(); 多态
*
* 多态的几种形式 :
* 1 直接多态 Animal a = new Animal();
* 2 形参和实参 : 方法声明时,参数列表需要接收父类类型,而方法调用时,传入子类对象
* public static void m1(Animal a){}
* m1(new Cat());
* 3 返回值 : 返回值类型是父类类型,但是返回的对象是子类对象
* public static Animal m2(){
* return new Cat();
* }
*
* 多态缺点 : 丢失子类特有的属性
* 使用多态进行调用 :
* 1 如果父类没有,不管子类有没有,都报错,因为丢失子类特有属性
* 2 如果父类有,子类没有,使用父类的,因为继承
* 3 如果父类有,子类也有,除了成员方法执行子类,其他都执行父类的(因为成员方法可以覆写)
*
public class Poly_01 {
public static void main(String[]args){
//多态 父类引用指向子类对象
Animal a=new Cat();
//调用成员方法 对象.成员方法()
a.eat();
}
}
//创建父类方法
class Animal{
public void eat(){
System.out.println("吃饭...");
}
}
//子类方法继承父类方法
class Cat extends Animal{
public void eat(){
System.out.println("猫吃鱼");
}
}
package java_12;
/**
* 多态好处
*
* 简单来说 : 高内聚,低耦合
* @author 18370
*
*/
public class Poly_02 {
public static void main(String[] args) {
Cat_01 c=new Cat_01();
eat(c);
Dog_01 d = new Dog_01();
eat(d);
Pig p=new Pig();
eat(p);
}
//需求 : 要求能够接收所有的动物对象,并调用对象的eat方法
// public static void eat(Cat_01 c){
//c.eat();
//public static void eat(Dog_01 d){
//d.eat();
//}
//多态写法,只要是动物的子类,都可以接收,所以后续想养什么宠物,这里也不需要调换
public static void eat(Animal_01 a){
a.eat();
}
}
//创建一个父类
class Animal_01{
public void eat() {
}
}
//创建一个子类 ,子类继承父类
class Cat_01 extends Animal_01{
int age=2;
public void eat(){
System.out.println("猫吃鱼");
}
}
class Dog_01 extends Animal_01 {
int age = 3;
public void eat() {
System.out.println("狗吃肉");
}
}
class Pig extends Animal_01{
//方法覆写:当父类方法满足不了子类需求的时候就要方法覆写
@Override
public void eat(){
System.out.println("吃白菜");
}
}
package java_12;
public class Poly_03 {
public static void main(String[]args){
//直接创建变量进行多态
SupClass sup=new SubClass();
//形参和实数多态:方法声明时参数列表需要接受父类类型,方法调用时需要传入子类
m1(new SubClass());
//返回值
SupClass sup2 =m2();
}
public static void m1(SupClass sup){
}
//返回值多态:返回值用父类,返回子类
public static SupClass m2(){
return new SubClass();
}
}
class SupClass{
}
class SubClass extends SupClass{
}
package java_12;
/**
* 比较隐秘的多态
*
* 总结 : 通过子类,调用了父类的方法的时候,父类的这个方法的上下文环境,就是多态环境(属于父类空间,子类对象)
* @author 18370
*
*/
public class Poly {
public static void main(String[]args){
//声明一个多态
Sup sup=new Sub();
System.out.println(sup.i);
//调用m2方法
sup.m2();
Sub sub=new Sub();
//System.out.println(sub.i);
//子类
//sub.m2();
sub.m1();
}
}
class Sup{
int i=2;
public void m1(){
//this:保存当前类对象的内存地址
//this:保存当前类对象的内存地址
//this:保存当前类对象的内存地址
//当前类:this出现在哪个类哪个类就是当前类
//并且this是第一个成员变量,既然是变量,肯定有数据类型
//那么this的类型是什么的时候可以存储当前类对象的地址?
//1.当前类类型(Sup)2.父类类型
//若果是父类类型,说明发生了多态,丢失特有属性,但是this可以调用当前类中所有的属性,所有this是当前类类型
//Sup this;
//this:用在成员方法中,那个对象调用了这个方法,this就指向哪个对象
// 在这里 m1是sub对象调用的,所以this 就指向 sub对象
// 而 sub是继承了Sup的
// 所以 等于是这样 Sup this = sub; Sub sub = new Sub(); 所以 Sup this = new Sub();
// 所以在这里 this 发生了多态
System.out.println(this.i);
this.m2();
}
public void m2(){
System.out.println("父类的m2");
}
}
//Sub作为子类继承了S
class Sub extends Sup{
int i=3;
public void m2(){
System.out.println("子类的m2");
}
}
package java_12;
/**
* 多态又叫向上转型
* 子类到父类是向上转型,父类到子类是向下转型
* 为什么需要向下转型呢?
*
* 因为多态会丢失子类特有的属性,想要调用子类特有的属性的时候,需要转型为对应的属性才行
* @author 18370
*
*/
public class Poly_05 {
public static void main(String[]args){
Animal_01 a=new Cat_01();
//调用不了,多态已经丢失了特有属性
//System.out.println(a.age);
m1(a);
//假如传递一个Dog类型就会报错
a =new Dog_01();
m1(a);
}
public static void m1(Animal_01 a){
//instanceof:判断某个对象是否由某个类实例化而来
if(a instanceof Cat_01){
Cat_01 c=(Cat_01) a;
System.out.println(c.age);
}else{
Dog_01 c=(Dog_01) a;
System.out.println(c.age);
}
}
}
抽象:抽象类往往用来表示设计中得到的抽象概念
*
* 比如动物 , 它就只是一个抽象的概念,并没有一个东西叫动物,没有对应的实体,这种情况下,我们适合把它定义为抽象类
*
* abstract 是个修饰符
*
* 修饰的类是抽象类, 不能创建对象,只是用于被继承
* 修饰的方法是抽象方法,并且该方法没有方法体(也就是{})
* 抽象方法必须在抽象类中,但是抽象类中不一定有抽象方法
*
* abstract和final 是二选一 , 因为final修饰的类不能被继承,成员方法不能被覆写
* 而 abstract修饰的抽象类就是用来被继承的,抽象方法就是用来被覆写实现的
*
* 一个非抽象类 继承一个抽象类,需要实现所有的抽象方法
* 一个抽象类继承一个抽象类 需要实现0~N个抽象方法
*
* 抽象类虽然不能创建对象,但是有构造方法,用于子类创建对象时调用
*
public class Abstract_01 {
public static void main(String[]args){
//Animal a=new Cat();
Animal a=new Cat();
a.eat();
}
}
abstract class Animal{
public Animal(){
}
public abstract void eat();
}
class Cat extends Animal{
@Override
public void eat(){
System.out.println("猫吃鱼");
}
}
class Dog extends Animal{
@Override
public void eat(){
System.out.println("狗吃肉");
}
}
package java_12;
public class Abstract_02 {
}
//abstract修饰的类可以被继承
abstract class A {
public abstract void m1();
public abstract void m2();
public abstract void m3();
}
class B extends A{
@Override
public void m1(){
//TODO Auto-generated method stub
}
@Override
public void m2() {
// TODO Auto-generated method stub
}
@Override
public void m3() {
// TODO Auto-generated method stub
}
}
//抽象类继承抽象类需要实现0~n个抽象方法
abstract class C extends A{
@Override
public void m1(){
}
}
class D extends C{
@Override
public void m1(){
//TODO Auto-generated method stub
}
@Override
public void m2() {
// TODO Auto-generated method stub
}
@Override
public void m3() {
// TODO Auto-generated method stub
}
接口:interface : 定义接口关键字 语法 : [权限修饰符] interface 接口名 { 类体 }
*
* 接口主要为了解决java中单继承功能变弱问题,一个类只能继承一个类,但是可以实现多个接口
*
* 1.8之前 接口是完全抽象的,只能有抽象方法和常量
*
* 1.8开始 接口中允许出现默认方法和静态方法
*
* 1 语法 [权限修饰符] interface 接口名 { 类体 }
* 2 接口中默认都是public的
* 接口中的变量都是常量,并且 public static final 可以省略,默认就是
* 接口中的抽象方法,public abstract 可以省略,默认就是
* 3 接口没有构造方法,同时不能创建对象
* 4 一个类只能继承一个类,但是可以实现多个接口
* [权限控制修饰符] class 类名 implements 接口名1,接口名2,....{}
* 一个类实现接口,必须实现接口中所有的抽象方法
* 一个抽象类,实现接口,需要实现0~N个抽象方法
* 5 接口和接口之间 是多继承,多个以逗号隔开
* [权限控制] interface 接口名 extends 父接口名1, 父接口名2,....{}
*
* 6 1.8开始 可以有静态方法和default方法(default方法就可以理解为成员方法,子实现类也可以覆写)
* 静态方法调用 : 接口名.方法名(参数);
* 默认方法调用 : 需要用 子实现类对象.方法名(参数);
*
* 1.9 开始 就开始支持private方法
*
public interface Interface_01 {
// 接口中没有变量,只有常量
public static final int xxx=2;
//public static final 可以省略,默认就是
int aaaa = 3;
// 抽象方法
public abstract void m1();
// public abstract 可以省略,默认就是
void m2();
// 静态方法
public static void m3() {
System.out.println("静态方法");
}
// 默认方法
default void m4() {
System.out.println("默认方法");
}
}
interface A{
void m1();
}
interface B{
void m2();
}
interface C{
void m3();
}
interface D extends A,B,C{
void m4();
}
class E implements A,C{
@Override
public void m3() {
}
@Override
public void m1() {
}
}