第六章:面向对象编程下

目录

6.1:static关键字

6.2:单例设计模式

6.3:类的成员之四:代码块

6.4:关键字:final

6.5:抽象类和抽象方法

6.6:interface(接口)

6.7:类的成员之五:内部类


6.1:static关键字
package com.jiayifeng.java;

import java.security.PublicKey;
import java.util.zip.CRC32;

/*
 * 一:关键字:static的使用
 * 1.static:关键的
 * 
 * 2.static:可以用来修饰:属性、方法、代码块、内部类
 * 
 * 3.使用static修饰属性:静态变量(或类变量)
 * 		3.1:属性,按是否使用static修饰,又分为:静态属性 vs 非静态属性(实例变量)
 * 			①实例变量:我们创建了类的多个对象,每个对象都独立的拥有一套类中的非静态属性。
 * 当修改其中一对象中的非静态属性时,不会导致其它对象中同样的属性值的修改
 * 			②静态属性:我们创建了类的多个对象,多个对象共享同一个静态变量。当通过某一个对象修 
 * 改静态变量时,会导致其它对象调用此静态变量时,是修改过了的
 * 		3.2:static修饰属性的其他说明
 * 			①静态变量随着类的加载而加载,可以通过"类.静态变量"的方法进行调用
 * 			②静态变量的加载要早于对象的创建
 * 			③由于类只会加载一次,则静态变量在内存中也只会存在一份:存在于方法区的静态域中
 * 			④		类变量			实例变量
 * 			类		yes				no
 * 			对象		yes				yes
 * 
 * 4.使用static修饰方法:静态方法
 *		①静态方法随着类的加载而加载,可以通过"类.静态方法"的方法进行调用
 *		②			静态方法			非静态方法
 *		类			yes				no
 *		对象			yes				yes
 *		③静态方法中,只能调用静态的方法或属性
 *		 非静态方法中,既可以调用非静态的属性或方法,也可以调用静态的属性或方法
 *
 * 5.static注意点
 * 		5.1:在静态的方法内,不能使用super关键字、this关键字
 * 
 * 6.在开发中,如何确定一个属性是否要声明为static?
 * 		>属性是可以被多个对象所共享的,不会随着对象的不同而不同
 * 		>类中的常量也常常声明为static
 * 	 在开发中,如何确定一个方法是否要声明为static?
 * 		>操作静态属性的方法,通常设置为static
 * 		>工具类中方法,习惯上声明为static
 */
public class StaticTest {
	public static void main(String[] args) {
		Chinese.nation = "CHINA";
		Chinese.show();
		
		Chinese c1 = new Chinese();
		c1.name = "姚明";
		c1.age = 40;
		
		Chinese c2 = new Chinese();
		c2.name = "马龙";
		c2.age = 30;
		
		c1.nation = "CHN";
		System.out.println(c2.nation);
	}
}

class Chinese{
	String name;
	int age;
	static String nation;
	
	public void eat() {
		System.out.println("中国人吃中餐");
	}
		
	public static void show() {
		System.out.println("我是一个中国人");
	}
}
6.2:单例设计模式
package com.jiayifeng.java1;
/*
 * 一:单例设计模式
 * 1.定义
 * 	    采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例

 * 2.实现
 * 		①饿汉式
 * 		②懒汉式

 * 3.区分饿汉式和懒汉式
 * 		饿汉式:
 * 			坏处:对象加载时间过长
 * 			好处:饿汉式是线程安全的
 * 		懒汉式:
 * 			好处:延迟对象的创建
 * 			坏处:懒汉式是线程不安全的
 *  
 */
public class SingletonTest1 {
	public static void main(String[] args) {
		 Bank bank1 = Bank.getInstance();
		 Bank bank2 = Bank.getInstance();
		 System.out.println(bank1 == bank2);
	}
}

//饿汉式
class Bank{
//	1.私有化类的构造器
	private Bank() {
		
	}
	
//	2.内部创建类的对象
//	4.要求此类对象也必须声明为静态的
	private static Bank instance = new Bank();
	
//	3.提供公共的静态的方法,返回类的对象
	public static Bank getInstance() {
		return instance;
	}
}
package com.jiayifeng.java1;
/*
 * 一:单例模式的懒汉式实现
 */
public class SingletonTest2 {
	public static void main(String[] args) {
		Order order1 = Order.getInstance();
		Order order2 = Order.getInstance();
		System.out.println(order1 == order2);
	}
}

class Order{
//	1.私有化类的构造器
	private Order() {
		
	}
	
//	2.声明当前类对象,没有初始化
//	4.此类对象也必须声明为static
	private static Order instance = null;
	
//	3.声明public、static的返回当前类对象的方法
	public static Order getInstance() {
		if(instance == null) {
			instance = new Order();
		}
		return instance;
	}
}
6.3:类的成员之四:代码块
package com.jiayifeng.java2;
/*
 * 一:类的成员之四:代码块(或初始化块)
 * 1.作用:用来初始化类、对象
 * 
 * 2.只能使用static来修饰
 * 
 * 3.分类:
 * 		静态代码块
 * 		非静态代码块
 * 
 * 4.静态代码块
 * 		>内部可以有输出语句
 * 		>随着类的加载而执行,而且只执行一次
 * 		>作用:初始化类的信息
 * 		>如果一个类中定义了多个静态代码块,则按照声明的先后顺序执行
 * 		>静态代码块的执行要优先于非静态代码块的执行
 * 		>静态代码块内只能调用静态的属性或方法,不能调用非静态的结构
 * 
 * 5.非静态代码块
 * 		>内部可以有输出语句
 * 		>随着对象的创建执行
 * 		>每创建一个对象,就执行一次非静态代码块
 * 		>作用:可以在创建对象的时候,对对象的属性进行初始化
 * 		>如果一个类中定义了多个非静态代码块,则按照声明的先后顺序执行
 * 		>非静态代码块内可以调用静态的属性或方法,也可以调用非静态的属性或方法
 * 
 * 对属性可以赋值的位置:
 * 	①默认初始化
 * 	②显式初始化
 * 	③构造器中初始化
 * 	④有了对象以后,可以通过"对象.属性"或"对象.方法"的方式,进行赋值
 * 	⑤在代码块中赋值
 */
public class BlockTest {
	public static void main(String[] args) {
		String desc = Person.desc;
		System.out.println(desc);
		Person person1 = new Person();
		Person person2 = new Person();
		System.out.println(person1.age);
		Person.info();
	}
}

class Person{
	String name;
	int age;
	static String desc = "我是一个人";
	
	public Person() {
		
	}
	
	public Person(String name,int age) {
		this.name = name;
		this.age = age;
	}
	
//	static代码块
	static{
		System.out.println("hello,static block");
		desc = "我是一个爱学习的人";
	}
	
//	非static代码块
	{
		System.out.println("hello,block");
		age = 1;
	}
	
	public void eat() {
		System.out.println("吃饭");
	}

	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + "]";
	}
	
	public static void info() {
		System.out.println("我是一个快乐的人!");
	}
}
6.4:关键字:final
package com.jiayifeng.java2;
/*
 * 一:final关键字
 * 1.final:最终的
 * 
 * 2.final可以用来修饰的结构:类、方法、变量
 * 
 * 3.final用来修饰一个类:此类不能被其它类所继承
 * 
 * 4.final用来修饰方法:此方法不能被重写
 * 
 * 5.final用来修饰变量:此时的"变量"就称为是一个常量
 * 		5.1.final修饰属性:可以考虑赋值的位置有:显式初始化、代码块中初始化、构造器中初始化
 * 		5.2.final修饰局部变量:
 * 			尤其是使用final修饰形参时,表明此形参是一个变量。当我们调用此方法时,给常量形参赋一个
 * 实参。一旦赋值以后,就只能在方法体内使用此形参,但不能进行重新赋值
 * 
 * static final:用来修饰属性:全局常量 
 * 				 用来修饰方法
 */
public class FinalTest {
	final int width = 10;
	final int WIDTH = 0;
	final int LEFT;
	final int RIGHT;
//	final int DOWN;
	
	{
		LEFT = 20;
	}
	
	public FinalTest() {
		RIGHT = 1;
	}
	
	public FinalTest(int n) {
		RIGHT = n;
	}
	
//	public void setDown(int dowm) {
//		
//	}
	
	public void dowidth() {
//		width = 20;
	}
	
	public void show() {
		final int NUM = 10; //常量
//		NUM += 20;
	}
	
	public void show(final int num) {
//		num = 20;
		System.out.println(num);
	}
	
	public static void main(String[] args) {
		int num = 10;
		num = num + 5;
		FinalTest test = new FinalTest();
//		test.setDown(3);
		test.show(4);
	}
}

final class FinalA{
	
}

class AA{
	public final void show() {
		
	}
}

class BB extends AA{
//	public void show() {
//		
//	}
}
6.5:抽象类和抽象方法
package com.jiayifeng.java3;
/*
 * 一:abstract关键字的使用
 * 1.abstract:抽象的
 * 
 * 2.abstract可以用来修饰类的结构:类、方法
 * 
 * 3.abstract修饰类:抽象类
 * 		>此类不可以实例化
 * 		>抽象类中一定有构造器,便于子类实例化时调用(涉及:子类对象实例化全过程)
 * 		>开发中,都会提供抽象类的子类,让子类进行实例化,完成相关操作
 * 
 * 4.abstract修饰方法:抽象方法
 * 		>抽象方法只有方法的声明,没有方法体
 * 		>包含抽象方法的类,一定是一个抽象类。反之,抽象类中可以没有抽象方法
 * 		>若子类重写父类中的所有的抽象方法后,此子类可实例化
 * 		>若子类没有重写父类中所有的抽象方法,则此子类也是一个抽象类,需要使用abstract修饰
 * 
 * 5.注意点
 * 		①abstract不能用来修饰:属性、构造器等结构
 * 		②abstract不能用来修饰私有方法、静态方法、final的方法、final的类
 */
public class AbstractTest {
	public static void main(String[] args) {
//		一旦Person类抽象了,就不可以实例化
//		Person p1 = new Person();
//		p1.eat();
	}
}

abstract class Person{
	String name;
	int age;
	
	public Person() {
		
	}
	
	public Person(String name,int age) {
		this.name = name;
		this.age = age;
	}
	
//	public void eat() {
//		System.out.println("人吃饭");
//	}
	
	public void walk() {
		System.out.println("人走路");
	}
	
//	抽象方法
	public abstract void eat();
}

class Student extends Person{
	public Student() {
		
	}
	
	public Student(String name,int age) {
//		this.name = name;
//		this.age = age;
		super(name,age);
	}
	
	public void eat() {
		System.out.println("学生多吃有营养的食物");
	}
	
	
}
6.6:interface(接口)
package com.jiayifeng.java4;
/*
 * 一:接口的使用
 * 1.接口使用关键字interface来定义
 * 
 * 2.Java中,接口和类是并列的两个结构,或者可以理解为接口是一种特殊的类
 * 
 * 3.如何定义接口:定义接口中的成员
 * 		3.1:JDK7及以前:只能定义全局常量和抽象方法
 * 			>全局常量:public static final,书写时,可以省略不写
 * 			>抽象方法:public abstract
 * 		3.2:JDK8:除了定义全局常量和抽象方法之外,还可以定义静态方法、默认方法
 * 
 * 4.接口中不能定义构造器,意味着不可以实例化
 * 
 * 5.Java开发中,接口通过让类去实现(implements)的方式来使用
 * 		如果实现类覆盖了接口中的所有抽象方法,则此实现类就可以实例化
 * 		如果实现类没有覆盖了接口中的所有抽象方法,则此实现类仍然为一个抽象类
 * 
 * 6.java类可以实现多个接口 -->弥补了java单继承性的局限性
 * 		格式:class AA extends BB implements CC,DD,EE
 * 
 * 7.接口和接口之间可以(多)继承
 * 
 * 8.接口的具体使用:体现多继承
 * 
 * 9.接口,实际上可以看作是一种规范
 * 
 * 10.接口的主要用途就是被实现类实现(面向接口编程)
 * 
 * 面试题:抽象类和接口有哪些异同?
 *     相同点:不能实例化
 *     不同点:抽象类:有构造器;接口:不能声明构造器
 * 
 */
public class InterfaceTest {
	public static void main(String[] args) {
		System.out.println(Flyable.MAX_SPEED);
		System.out.println(Flyable.MIN_SPEED);
//		Flyable.MIN_SPEED = 2;
		
		Plane plane = new Plane();
		plane.fly();
	}
}

interface Flyable{
//	全局常量
	public static final int MAX_SPEED = 7900; //第一宇宙速度
	int MIN_SPEED = 1; //省略了public static final
	
//	抽象方法
	public abstract void fly();
//	省略了public abstract
	void stop();
}

interface Attackable{
	void attack();
}

class Plane implements Flyable{
	@Override
	public void fly() {
		System.out.println("通过引擎起飞");
	}

	@Override
	public void stop() {
		System.out.println("驾驶员减速停止");
	}
}

class Bullet extends Object implements Flyable,Attackable{

	@Override
	public void attack() {
		
	}

	@Override
	public void fly() {
		
	}

	@Override
	public void stop() {
		
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
interface AA{
	
}

interface BB{
	
}

interface CC extends AA,BB{
	
}
package com.jiayifeng.java4;
/*
 * 一:接口的使用
 * 1.接口使用上满足多态性
 * 
 * 2.接口实际上就是定义了一种规范
 * 
 * 3.开发中,体会面向接口编程·
 * 
 */
public class USBTest {
	public static void main(String[] args) {
		Computer computer = new Computer();
//		1.创建了接口的非匿名实现类的非匿名对象
		Flash flash = new Flash();
		computer.transferData(flash);
		
//		2.创建了接口的非匿名实现类的匿名对象
		computer.transferData(new Printer());
		
//		3.创建了接口类的匿名实现类的非匿名对象
		USB phoneUsb = new USB() {
			
			@Override
			public void start() {
				System.out.println("手机开始工作");
			}
			
			@Override
			public void end() {
				System.out.println("手机结束工作");
			}
		};
		computer.transferData(phoneUsb);
		
//		4.创建了接口的匿名实现类的匿名对象
		computer.transferData(new USB() {
			
			@Override
			public void start() {
				System.out.println("MP3开始工作");
			}
			
			@Override
			public void end() {
				System.out.println("MP3结束工作");
			}
		});
	}
}

class Computer{
	public void transferData(USB usb) {
		usb.start();
		System.out.println("具体传输数据的细节");
		usb.end();
	}
}

interface USB{
//	常量:定义了长、宽、高、最大最小的传输速度等
	void start();
	
	void end();
}

class Flash implements USB{

	@Override
	public void start() {
		System.out.println("U盘开始工作");
	}

	@Override
	public void end() {
		System.out.println("U盘结束工作");
	}
	
}

class Printer implements USB{

	@Override
	public void start() {
		System.out.println("打印机开始工作");
	}

	@Override
	public void end() {
		System.out.println("打印机结束工作");
	}
	
}
package com.jiayifeng.java5;

public class SubClassTest {
	public static void main(String[] args) {
		SubClass subClass = new SubClass();
//		subClass.method1();
//		1.接口中定义的静态方法,只能通过接口来调用
//		2.通过实现类的对象,可以调用接口中的默认方法
//		3.如果实现类重写了接口中的默认方法,调用时,任然调用的是重写以后的方法
		CompareA.method1();
		subClass.method2();
//		4.如果子类(实现类)继承的父类和实现的接口中声明了同名同参数的方法,
//		那么子类在没有重写此方法的情况下,默认调用的是父类中的同名同参的方法 --类优先原则
//		5.如果实现类实现了多个接口,而这多个接口中定义了同名同参数的默认方法,
//		那么在实现类没有重写此方法的情况下,会报错 --接口冲突
//		解决:需要在实现类中重写此方法
		subClass.method3();
		
	}
}

class SubClass extends SuperClass implements CompareA,CompareB {
	public void method2() {
		System.out.println("SubClass:上海");
	}

	@Override
	public void method3() {
		System.out.println("SubClass:深圳");
	}
	
//	6.如何在子类(实现类)的方法中调用父类、接口中被重写的方法
	public void myMehod() {
		method3(); //调用自己定义的重写的方法
		super.method3(); //调用的是父类中声明的
//		调用接口中的默认方法
		CompareA.super.method3();
		CompareB.super.method3();
	}
}
6.7:类的成员之五:内部类
package com.jiayifeng.java6;

import java.nio.channels.NonWritableChannelException;

/*
 * 一:内部类的使用
 * 1.Java中允许将一个类A声明在另一个类B中,则类A就是内部类,类B称为外部类
 * 
 * 2.内部类的分类:成员内部类(静态、非静态) vs 局部内部类(方法内、代码块内、构造器内)
 * 
 * 3.①成员内部类:
 * 		一方面,作为外部类的成员:
 * 			>调用外部类的结构
 * 			>可以被static修饰
 * 			>可以被四种权限修饰:
 * 
 * 		另一方面,作为一个类
 * 			>类内可以定义属性、方法、构造器
 * 			>可以被final修饰,表示此类不能被继承
 * 			>可以被abstract修饰
 * 	②局部内部类:在局部内部类的方法中,如果调用局部内部类所声明的方法中的局部变量,则
 *  要求此局部变量声明为final
 *  	jdk 7及以前版本:要求此局部变量显式的声明为final
 *  	jdk 8及以后的版本:可以省略final的声明
 * 
 * 4.关注如下的三个问题
 * 		4.1:如何实例化成员内部类的对象
 * 		4.2:如何在成员内部类中区分调用外部类的结构
 * 		4.3:开发中局部内部类的使用《见InnerClassTest1.java》
 * 
 * 5.总结:
 * 		成员内部类和局部内部类在编译以后,都会生成字节码文件
 * 		格式:
 * 			成员内部类:外部类$内部类名.class
 * 			局部内部类:外部类$数字 内部类名.class
 */
public class InnerClassTest {
	public static void main(String[] args) {
//		4.1:
//		创建Dog实例(静态的成员内部类)
		Person.Dog dog = new Person.Dog();
		dog.show();
		
//		创建Bird实例(非静态的成员内部类)
		Person person = new Person();
		Person.Bird bird  = person.new Bird();
		bird.sing();
		System.out.println("*************************");
		
		bird.display("黄鹂");
	}
}

class Person{
	String name = "小明";
	int age;
	public void eat() {
		System.out.println("人:吃饭");
	}
//	静态成员内部类
	 static class Dog{
		String name;
		int age;
		public void show() {
			System.out.println("卡拉是条狗");
		}
	}
	
//	非静态成员内部类
	 class Bird{
		String name = "杜鹃";
		public Bird(){
			
		}
		
		public void sing() {
			System.out.println("我是一只小小鸟");
			eat(); //调用外部类的非静态属性
		}
		
		public void display(String name) {
			System.out.println(name); //方法的形参
			System.out.println(this.name); //内部类的属性
			System.out.println(Person.this.name); //外部类的属性
		}
	}
	
	public void method() {
//		局部内部类
		class A{
			
		}
		
//		局部内部类
		class B{
			
		}
	}
	
	public Person() {
//		局部内部类
		class C{
			
		}
	}
}
package com.jiayifeng.java6;

public class InnerClassTest1 {
//	返回一个实现了Comparable接口的类的对象
	public Comparable getComparable() {
		创建一个实现了Comparable接口的类:局部内部类
		方式一:
//		class Mycomparable implements Comparable{
//
//			@Override
//			public int compareTo(Object o) {
//				// TODO Auto-generated method stub
//				return 0;
//			}
//			
//		}
//		return new Mycomparable();
		
//		方式二:匿名实现类的对象
		return new Comparable() {

			@Override
			public int compareTo(Object o) {
				// TODO Auto-generated method stub
				return 0;
			}
		};
	}
}

猜你喜欢

转载自blog.csdn.net/weixin_63925896/article/details/132294900