Java 进阶学习笔记day_02(static关键字、接口、多态)

static关键字_


  • static是一个关键字,表示静态的意思,可以用来修饰成员变量,成员方法,代码块

格式: 修饰符 static 数据类型 变量名;

  1. 被static修饰的成员变量叫做静态成员变量\类变量
  2. 被static修饰的成员变量会被该类的所有对象共享
  3. 如果该类的某个对象修改了静态成员变量的值,那么该类的所有对象使用的都是修改后的值

访问方式:

  • 对象名.静态成员变量名
  • 类名.静态成员变量名 (推荐)

示例:


	class Text{
		// 非静态成员变量
		int a;

		// 静态成员变量 
		static int b = 50;		
}

	public class Demo{
		public static void main(String[] args) {
			Text tx = new Text();
			tx.a = 10;
			tx.b = 20;
	
			System.out.println(tx.a + "," + tx.b); // 输出 10,20

			Text tx2 = new Text();
			System.out.println(tx2.a + "," + tx2.b); // 输出 0,20
				
			Text.b = 30;
			System.out.println(Text.b); // 输出 30
			
	}
}

被static修饰的成员变量叫做静态成员变量\类变量
被static修饰的成员变量会被该类的所有对象共享(相当于全局变量)
如果该类的某个对象修改了静态成员变量的值,那么该类的所有对象使用的都是修改后的值

修饰成员方法_


	修饰符 static 返回值类型 方法名(形参列名){
    方法体
}
  • 被static修饰的成员方法叫做静态方法

访问方式

  • 对象名.方法名(实参/无参);
  • 类名.方法名(实参/无参); (推荐)

示例:


	class Text2{
		// 非静态成员方法
		public void show(){
			System.out.println("非静态方法 show...");
		}

		// 静态成员方法 
		static public void show2(){
			System.out.println("静态方法 show2...");
		}
}

	public class Demo2{
		public static void main(String[] args) {
			Text2.show2(); // 输出 静态方法 show2...
			
			// 用对象访问
			Text2 tx = new Text2();
			tx.show();
			tx.show2();
		}
	}
  • 注意事项

静态方法中不能出现this关键字
静态方法中只能直接访问静态成员变量和静态成员方法
静态方法中不能直接访问非静态成员变量和非静态成员方法
非静态方法中可以直接访问一切成员变量和成员方法

修饰代码块_


	static {
    // 静态代码块
}
  • 静态代码块所在位置( 类中方法外(类的成员位置) )
  • 随着类的加载而执行,并且只执行一次
  • 类的加载: 第一次使用该类的时候,就会加载,并且只加载一次
  • 如果程序中某段代码只需要执行一次,就可以把该段代码放入静态代码块中 ( 比如加载驱动,读取配置文件中的数据… )

接口_

  • 接口是Java语言中的一种引用类型,主要是用来存储方法的

接口中的成员:

  • 常量
  • 抽象方法
  • 默认方法和静态方法 (JDK 8)
  • 私有方法(JDK 9及以上)

定义接口需要使用interface关键字 (编译后也会产生class文件)
接口没有构造方法,也不能创建对象,所以一般都是供类实现的(implements),类似继承
实现接口的类叫做实现类,实现类如果是普通类必须重写接口中所有的抽象方法,否则实现类是一个抽象类

示例:

	// 定义了一个接口 A
	public interface A{
		// 定义一个静态常量 (public static final修饰,而这三个修饰符可以省略不写)
		public static final int NUM = 20;
		// 定义一个抽象方法 (public abstract修饰,而这两个修饰符可以省略不写)
		public abstract void show();
		// 定义一个默认方法 (public default修饰,public可以省略不写,default不可以省略)
		public default void show2(){
			// 方法体
		}
		// 定义一个静态方法 (public static修饰,public可以省略不写,static不可以省略)
		public static void show(){
			// 方法体		
		}
}

实现接口_

	// 单实现
	public class 实现类名 implements 接口名{}

	// 多实现
	public class 实现类名 implements 接口名1,接口名2,接口名3,...{}
	
	// 先继承后实现
	public class 实现类名 extends 父类名 implements 接口名1,接口名2,接口名3,...{}

示例:


	interface A{}
	interface B{}
	interface C{}

	class Fu{}

	// 单实现
	class Zi implements A{}

	// 多实现
	class Zi2 implements A,B,C{}

	// 先继承后实现
	class Zi3 extends Fu implements A,B,C{}

接口中成员的访问特点_

  • 接口中常量: 主要供接口名直接访问,也可以被实现类继承
  • 接口中抽象方法:就是供实现类重写的
  • 接口中默认方法:可以供实现类对象直接调用,或者在实现类中重写
  • 接口中静态方法:只供接口名直接访问,不可以被实现类继承
  • 接口中私有方法:只能在接口内部方法中调用,不可以被实现类继承

示例:


	interface A{
		int NUM = 20;
		
		void show();
		
		default void show2(){
			System.out.println("我是默认方法");
		}

		static void show3(){
			System.out.println("我是静态方法");
		}
		
		private void show4(){
			System.out.println("我是私有方法");
		}
}

	class Imp implements A{
		@Override
    	public void show() {
        System.out.println("重写接口A的show方法"); // 必须重写否则实现类为抽象类
	
		@Override
    	public void show2() {
        System.out.println("重写接口A的show2方法");
    }		
}

	public class Text{
		public static void main(String[] args) {
			// 访问接口中的常量
			A.NUM;
			Imp.NUM;

			// 访问接口中的抽象方法
			Imp = ip = new Imp();
			ip.show();

			// 访问接口中的默认方法
			ip.show2();
			
			// 访问接口中的静态方法
			A.show3();
		}
}

多实现时的几种冲突情况_

  • 公有静态常量的冲突 (多实现常量冲突: 多个接口中同名的常量不能被实现类继承)
  • 公有抽象方法的冲突 (抽象方法冲突: 必须重写一次抽象方法)
  • 公有默认方法的冲突 (默认方法的冲突: 必须重写一次默认方法)

接口和接口的关系_

  • 接口和接口之间是继承关系

	// 单继承
	public interface A{}
	public interface B extends A{}

	// 多继承
	public interface A{}
	public interface B{}
	public interface C extends A,B{}

	// 多层继承
	public interface A{}
	public interface B extends A{}
	public interface C extends B{}

接口继承接口的冲突情况_

  • 公有静态常量的冲突 (常量冲突: 多个接口中同名的常量不会被子接口继承,不同名的会被继承)
  • 公有抽象方法冲突 (抽象方法冲突: 多个父接口中有相同的抽象方法,子接口只会继承一个抽象方法)
  • 公有默认方法的冲突 (默认方法冲突: 多个父接口中有相同的默认方法,子接口必须重写默认方法(default))

继承的同时又实现存在的问题_

  • 父类和接口的公有静态常量的冲突 (常量冲突: 实现类不会继承有冲突的常量)
  • 父类和接口的抽象方法冲突 (抽象方法冲突: 实现类必须重写一次有冲突的抽象方法)
  • 父类和接口的公有默认方法的冲突 (默认方法的冲突: 优先访问父类的

多态_

  • 实现多态的前提条件
    继承或者实现
    父类引用指向子类对象 : Fu f = New Zi();
    方法的重写(没有重写方法多态是没有意义的)

实现多态_

继承时的多态:


	abstract class Animal{
    public abstract void eat();
}

	class Dog extends Animal{
	    @Override
	    public void eat() {
	        System.out.println("狗吃骨头...");
	    }
}

	class Cat extends Animal{
	    @Override
	    public void eat() {
	        System.out.println("猫吃鱼...");
    }
}


	public class Test {
    public static void main(String[] args) {
		// 继承实现多态的三个条件 
		// 1,继承
		// 2,父类的引用指向子类的对象
		// 3,方法的重写
		
		// 父类的引用指向子类的对象
		Animal an = new Dog();
		an.eat(); // 输出 狗吃骨头...

		an = new Cat();
		an.eat(); // 输出 猫吃鱼...
	}
}

实现时的多态:


	interface A{
    void show();
}

class Imp implements A{

    @Override
    public void show() {
        System.out.println("实现类重写的show...");
    }
}

class Imp2 implements A{
	@Override
    public void show2() {
        System.out.println("实现类重写的show2...");
    }
}

public class Test {
    public static void main(String[] args) {
        
            //实现多态的三个条件:
            //1,实现
            //2,接口的引用指向实现类的对象
            //3,方法的重写  
       
       	// 接口的引用指向实现类的对象
        A a = new Imp();
        a.show(); // 输出 实现类重写的show...
        
        a = new Imp2();
        a.show(); // 输出 实现类重写的show2...
    }
}

多态r的几种表现形式_

  • 普通父类多态

	public class Fu{}
	public class Zi extends Fu{}
	public class Test{
    public static void main(String[] args){
        Fu f = new Zi();// 多态
    }
}
  • 抽象父类多态

	public abstract class Fu{}
	public class Zi extends Fu{}
	public class Test{
    public static void main(String[] args){
        Fu f = new Zi();// 多态
    }
}
  • 父接口多态

	public interface IA{}
	public class Imp implements IA{}
	public class Test{
    public static void main(String[] args){
        IA a = new Imp();// 多态
    }
}

形参多态_

形参多态(常用)
参数的类型是父类类型,那么就可以接收该父类类型的对象以及该父类类型的所有子类对象

示例:


	class Fu{
	    public void show(){
	        System.out.println("ff");
	    }
	}
	
	class Zi extends Fu{
	    public void show(){
	        System.out.println("Zi");
	    }
	}
	class Zii extends Fu{
	    public void show(){
	        System.out.println("Zii");
	    }
	}

public class Text {
    public static void main(String[] args) {
        show(new Zi()); // 输出 Zi
        show(new Zii()); // 输出 Zii

    }
    public static void show(Fu f){
        f.show();
    }

}

返回值多态(常用)
返回值类型为父类类型,那么就可以返回该父类类型的对象,或者该父类类型的子类对象

示例:


	class Fu{
    public void show(){
        System.out.println("ff");
    	}
	}

	class Zi extends Fu{
	    public void show(){
	        System.out.println("Zi");
	    }
	}
	class Zii extends Fu{
	    public void show(){
	        System.out.println("Zii");
    	}
	}

	public class Text {
    	public static void main(String[] args) {
	        show("Zi").show(); // 输出 Zi
	        show("Zii").show(); // 输出 Zii

    }
    public static Fu show(String tyep){
        if("Zi".equals(tyep)){
            return new Zi();
        }else if("Zii".equals(tyep)){
            return new Zii();
        }else{
            return null;
        }
    }

}

引用类型转换_

  • 向上转型: 父类类型 变量名 = new 子类名(实参);
  • 向下转型: 子类类型 变量名 = (子类类型) 父类类型的变量;

为了避免转型异常一般会使用instanceof关键字来进行判断

  • 格式: 变量名 instanceof 数据类型

如果变量指向的对象的数据类型是属于后面的数据类型,就返回true,否则返回false

示例:


	class Fu{}

	class Zi extends Fu{

	    public void show(){
	        System.out.println("Zi");
	    }
	    public void zi(){
	        System.out.println("子类独有");
	    }
	}
	
	class Zii extends Fu{
	    
	    public void show(){
	        System.out.println("Zii");
	    }
	}


	public class Text {
	    public static void main(String[] args) {
	        Fu f = new Zi();

	        // 使用if 判断
	        if(f instanceof Zi){
	            Zi z = (Zi)f;
	            z.zi(); // 输出 子类独有
	        }
        
	        boolean b = (f instanceof Zii);
	        System.out.println(b); // 输出 false
   		}
	}

内部类_

  • 定义在类的成员位置(类中方法外)的类就叫做成员内部类

	class 外部类名{
    	class 内部类名{
        
    	}
}
  • 成员访问特点
    成员内部类中的成员变量和成员方法在其他类中访问,需要创建成员内部类对象
    外部类名.内部类名 对象名 = new 外部类名().new 内部类名();

示例:


	class On{
    int num = 10;

    class In{
        int num = 20;
        public void show(){
            System.out.println("我是内部类");
        }
    }
}

	public class Text {
	    public static void main(String[] args) {
	        On.In oi = new On().new In();
	        System.out.println("oi.num = " + oi.num);// 输出 oi.num = 20
	        oi.show();// 输出 我是内部类
	    }
}
  • 注意事项:

在成员内部类中,可以直接访问外部类的一切成员,包括外部类的私有成员
在外部类中,需要直接访问内部类的成员,需要创建内部类对象来访问

匿名内部类_

  • 本质其实就是一个类的子类对象
  • 本质其实就是一个接口的实现类对象

	new 类名(){
    必须重写所有抽象方法
	};

	new 接口名(){
    必须重写所有抽象方法
	};
  • 使用场景
    如果想得到一个抽象类的子类对象,那么就可以直接给该类的匿名内部类
    如果想得到一个接口的实现类对象,那么就可以直接给该接口的匿名内部类

示例:

	
	abstract class On{
	    int num = 10;
	    public abstract void show();
	}

	public class Text {
	    public static void main(String[] args) {
	        On o = new On(){
	
	            @Override
	            public void show() {
	                System.out.println("匿名内部类");
	            }
	        };
	        System.out.println(o.num); // 输出 10
	        o.show();// 输出 匿名内部类
	    }
	}

示例:


	interface On{
    int NUM = 10;
    public abstract void show();
}

public class Text {
    public static void main(String[] args) {
        On o = new On(){

            @Override
            public void show() {
                System.out.println("接口的内部类");
            }
        };
        System.out.println(o.NUM); // 输出 10
        o.show();// 输出 接口的内部类
    }
}

引用类型的使用_

  • 引用类型作为方法参数和返回值:
    引用类型作为方法的参数传递的是地址值
    引用类型作为方法的返回值返回的是地址值

示例:


	class Fu{
    String name = "张三";
    int age = 33;
    public void show(){
        System.out.println("引用类型作为参数和反回值");
    }
}

	public class Text {
	    public static void main(String[] args) {
	        Fu f = new Fu();
	        f.show(); // 输出 引用类型作为参数和反回值
	
	        Fu f2 = show(f);
	        System.out.println(f2.name); // 输出 张三

    }
    public static Fu show(Fu f){

        System.out.println(f.age); // 输出 33 
        return f;

    }
}

引用类型作为成员变量_

示例:


	class Demo1{
    String name;
    public void show(){
        System.out.println("Demo1");
    }
	}

	class Demo2{
	    String name;
	
	    Demo1 dm;
	}

	public class Text {
	    public static void main(String[] args) {
	        Demo2 dm2 = new Demo2();
	
	        dm2.dm = new Demo1();
	
	        dm2.dm.show();
	        dm2.name = "张三";
	        System.out.println(dm2.name);
	        
	}

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值