Java-笔记4

一.final

final修饰局部变量:

基本数据类型:如果局部变量是一个基本数据类型,那么被final修饰,基本数据类型的变量的值不能改变!

引用数据类型:如果用final修饰引用类型的变量,那么它不能在重写分配堆内存空间,但是可以改变成员变量的值.

相关代码:

class Student{
	int age;
}
public class FinalTest {
	public static void main(String[] args) {
		int num=10;
		num=20;
		System.out.println(num);
		System.out.println("-----------");
		
		final int num2=30;
//		基本数据变量的值不能改变
//		num2=40;
		System.out.println(num2);
		System.out.println("-----------");
		
		Student s=new Student();
		s.age=10;
		System.out.println(s.age);
		System.out.println("-----------");
		
		final Student ss=new Student();
		ss.age=20;
		System.out.println(ss.age);
		ss.age=30;
		System.out.println(ss.age);
		
//		不能重新分配堆内存空间
//		ss=new Student();
		
	}
}
结果为:20
-----------
30
-----------
10
-----------
20
30
二.多态

1.多态:一个事物在不同时刻体现出的不同状态.

2多态的三个前提:

1>必须有继承关系(没继承谈不上多态);

2>必须有方法重写;

3>有父类引用指向子类对象:向上转型

Fu zi = new zi();

三个条件缺一不可.

3,多态的成员访问特点:

成员变量:

编译看左,执行看左;

成员方法(飞静态成员方法):

编译看左,执行看右;由于存在方法重写,所以最终运行的是子类成员方法;

静态成员方法:

编译看左,运行看左;

构造方法:

对象进行初始化,由于是一种继承关系,所以还是分层初始化!

相关代码:

class Fu{
	public int num=10;
	public void show(){
		System.out.println("show Fu");
	}
	public static void function(){
		System.out.println("function Fu");
	}
}
class Zi extends Fu{
	int num=20;
	public void show(){
		System.out.println("show Zi");
	}
	public static void function(){
		System.out.println("function Zi");
	}
}
//	测试类
public class DuoTaiDemo {
	public static void main(String[] args) {
//		创建对象(多态形式),由父类引用转向子类对象:向上转型
		Fu f=new Zi();
//		访问成员变量
		System.out.println(f.num);
//		调用成员方法:show
		f.show();
//		调用静态方法:function
		f.function();
	}
}
结果为:10
show Zi
function Fu

多态的好处(特点):

1)提高代码的维护性(由继承保证)

2)提高代码的扩展性(由多态保证)

Java的开发原则:低耦合,高内聚.

多态的弊端:

不能访问子类的特有功能:异常:OOM异常:严重:OutOfMemory:内存溢出!

解决方案:
* 1)创建子类的具体对象,来访问自己的特有功能;虽然可以解决多态的弊端,但是从内存角度考虑,需要创建子类对象,那么必须在堆内存开辟空间,
* 耗费内存,浪费空间!
* 2)既然多态的第三个前提条件:父类引用指向子类对象,那么可不可以将子类的引用指向父类对象呢?
* 可以的:向下转型:将父类的引用强制转换为子类的引用:前提必须有父类的引用存在;
* 向下转型必须依赖于向上转型!

相关代码:

class Animal{
	public void show(){
		System.out.println("show Animal");
	}
}
class Cat extends Animal{
	public void show(){
		System.out.println("show Cat");
	}
	//特有功能
	public void eat(){
		System.out.println("show eat");
	}
}
//	测试类
public class DuoTaiDemo {
	public static void main(String[] args) {
		//由父类引用指向子类对象
		Animal a=new Cat();
		a.show();
		//不能调用子类特有功能
//		a.eat();
		//创建子具体对象
		/*Cat c=new Cat();
		c.show();
		c.eat();*/
		//父类的引用强制转化为子类的引用:向下转换
		Cat c=(Cat) a;
		c.eat();
		
	}
}
结果为:show Cat
show eat
一般情况下:向下转型使用不当会造成一个异常:
Throwable:
error:严重问题
Exception:
编译时期异常:
运行时期异常:RuntimeException

运行时期异常:
ClassCastException:类转换异常:org.westos_02_多态.Cat4 cannot be cast to org.westos_02_多态.Dog4

相关部分代码:
//测试类:
public class DuoTaiDemo5 {
	public static void main(String[] args) {
		//内存是狗
		Animal4 a = new Dog4() ;
		//向下转型:还原成狗
		Dog4 d = (Dog4)a ;
		
		//内存是猫
		a = new Cat4() ;
		//还原成猫
		Cat4 c = (Cat4) a ;
		
		//编译通过了
		Dog4 dd = (Dog4)a ; //不能将内存猫转换为狗
	}
}
相关图解:


三.抽象类

抽象类概念:一个类中有抽象方法,那么这个类一定定义为抽象类!

当然一个抽象类可以抽象,也可以有抽象的(判断题!).

抽象类不能实例化:

抽象类想要实例化必须通过抽象类多态形式:父类的引用指向子类对象.

因此子类不能是抽象类!

抽象类多态:

强制子类重写父类所有的抽象方法,可以提高代码的维护性(继承关系保证!).

抽象类的方法特点:

成员方法:

可以使变量也可以是自定义常量!

构造方法:

抽象类有构造方法,当然可有参可无参构造!

成员方法:

可有抽象方法和非抽象方法!

非抽象方法:由继承提高代码的复用性.

相关代码:

abstract class Animal{
	//成员变量
	private String name;
	private int age;
	//无参构造
	public Animal(){
		
	}
	//有参构造
	public Animal(String name,int age){
		this.name=name;
		this.age=age;
	}
	//抽象方法
	public abstract void show();
//	具体方法
	public void print(){
		System.out.println("Animal");
	}
}
class Cat extends Animal{

	@Override
	public void show() {
		System.out.println("show Cat");
	}

}
//测试类
public class AbstractDemo {
	public static void main(String[] args){

		//父类引用指向子类对象
		Animal a=new Cat();//Animal抽象类,需要抽象多态形式
		//访问抽象方法
		a.print();
		a.show();
	}
}
结果为:Animal
show Cat

注意:一个类如果没有抽象类,也可以定义为抽象类!

private,final,static不能与abstract共同使用!


四.接口

接口的概念:体现一种扩展功能.

接口的表示:interface 接口名

接口里只能有抽象方法,没有构造方法.

接口的特点:不能被实例化.因此只能通过接口的子类实现,子类只能是非抽象类.

成员变量:只能是常量;默认符号为:public static final

成员方法:接口里的成员方法默认修饰符:public abstract;

接口的子实现类与接口的关系:implments

格式:class 子实现类 implments 接口名.

相关代码:

interface Inter{
	//成员变量
	public static final int num=10;
	//成员方法
	public abstract void show();
}
class InterImp implements Inter{

	@Override
	public void show() {
	System.out.println(num);
		
	}
	public void say(){
		System.out.println("I love you");
	}
}
public class InterfaceDemo {
	public static void main(String[] args) {
		//创建对象:使用多态
		Inter i=new InterImp();
		i.show();
		InterImp ii=(InterImp) i;//向下转换
		ii.say();
	}
}
结果为:10
I love you
类与类的关系:继承关系:extends,Java中只支持单继承,不支持多继承,但可以多层继承!

类与接口的关系:实现关系:implements,一个类在继承另一个类的时候,可以实现多个接口!

接口与接口的关系:继承关系:extends,可以支持单继承,也可以多继承!

格式:class 子实现类 extends Object implements 接口1,接口2...
五.API

API的使用:打开API:
显示---->输入你查找的类
索引---->搜索
找到某一个类:
对该类的描述
看类结构:
看该类是否有字段(变量),构造方法(如何创建该类对象),方法(类的成员方法)
出现该类的版本号:
Scanner java.util.Scanner;
JDK5.0以后的新特性:自动拆装箱(int--->Integer,char--->Character),静态导入(导入的方法级别),可变参数,增强for循环(集合),枚举
JDK7.0也有新特性(匿名内部类:局部内部类访问局部变量特性:局部变量必须被final讲)

制作API文档的相关代码:

/**
 * 该类是针对数组操作的一个工具类,里面有一些对数组操作的功能
 * @author Apple
 * @version V1.0
 * */
public class ArrayTool {
	//无参构造私有,目的为了不让外界其对象
	private ArrayTool(){
		
	}
	/**
	 * 该方法是针对数组的遍历的方法,遍历的元素[元素1, 元素2, 元素, ....]
	 * @param   arr :需要被遍历的数组
	 * */
	public static void printArray(int[] arr){
		System.out.print("[");
		for(int x = 0 ; x < arr.length ; x ++){
			if(x==arr.length-1){
				System.out.println(arr[x]+"]");
			}else{
				System.out.print(arr[x]+", ");
			}
		}
	}
	/**
	 * 该方法是针对数组获取最大值的方法
	 * @param  arr :需要被遍历的 数组,可以获取每一个元素
	 * @return 返回的就是数组中最大值
	 * 
	 * */
	public static int getMax(int[] arr){
		//定义参照物
		int max = arr[0] ;
		//遍历其他索引
		for(int x = 1 ; x < arr.length ;x ++){
			//判断
			if(arr[x]>max){
				max = arr[x] ;
			}
		}
		return max ;
	}
	
	/**
	 * 该方法是查询数组中的元素在数组中第一次出现的索引
	 * @param    arr : 需要查询的数组
	 * @param	 value:需要被查找的远古时
	 * @return 	如果查到了当前索引对应的元素,那么就直接返回当前索引,如果查不到,则返回-1
	 * */
	public static int getIndex(int[] arr,int value){
		//假设法
		//定义一个索引:假设查不到
		int index = -1 ;
		//遍历数组
		for(int x = 0 ; x < arr.length ; x ++){
			//判断:如果刚好查到的x索引对应的元素和value相等,那么返回该索引
			if(arr[x]==value){
				//表查到了
				//给索引遍历重新赋值
				index  = x ;
				break ;
			}
		}
		return index ;
	}
}
/**
 * 1)需要定义一个类工具类:ArrayTool数组工具类:给该类写上文档注释(每一个静态方法都需要使用文档注释)
 * 2)需要将该类的无参私有化,目的是为了让外界创建对象
 * 3)ArrayTool中的成员方法全部用static修饰
 * 4)测试完毕
 * 5)如何制作API文档
 * 		针对ArrayTool来制作
 * 打开dos---->javadoc -d 目标名(文件名) -author -version ArrayTool.java
 * */
public class ArrayDemo {
	public static void main(String[] args) {
		//定义一个数组,静态初始化
		int[] arr = {24,69,80,57,13} ;
		//遍历数组
		ArrayTool.printArray(arr) ;
		
		//获取数组中的最大值
		int result = ArrayTool.getMax(arr) ;
		System.out.println("result:"+result);
		
		//查询577元素
		int index = ArrayTool.getIndex(arr, 577) ;
		System.out.println("index:"+index);
		
		int index2 = ArrayTool.getIndex(arr, 57) ;
		System.out.println("index2:"+index2);	
	}
}
六.内部类

内部类概念:在一个类中定义另一个类.

内部类是直接可以访问外部类的成员,包括私有.

外部类想访问内部类,必须创建内部类的对象访问该内部类的成员. 

内部类的分类:

成员内部类:在外部类的成员位置.

局部内部类:在外部类的局部位置定义这个类.
访问成员内部类:

外部类名.内部类名 对象名=外部对象.内部对象

要访问外部类的成员变量:匿名对象 :new 外部类名().成员变量

成员内部类的修饰符:

private :为了保证数的安全性.直接创建外部类对象.

static修饰:为了方便调用

如果成员内部类被static修饰,那么外部类必须要被static修饰

静态成员内部类访问该类中的方法:

格式:外部类名.内部类名 对象名=new 外部类名.内部类名();

相关代码:

class Outer{
	//成员变量
	public int num=10;
	public static int  num1=20;
	//成员内部类(非静态)
	class Inter1{
		public void show(){
			System.out.println(num);
			System.out.println(num1);
		}
	}
	//成员内部类(静态)
	public static class  Inter2{
		//非静态方法
		public void show(){
//			System.out.println(num);
			System.out.println(num1);
		}
		public static void show1(){
//			System.out.println(num);
			System.out.println(num1);
		}
	}
}
public class InnerDemo {
	public static void main(String[] args) {
		Outer.Inter1 oi1=new Outer().new Inter1();
		oi1.show();
		System.out.println("------------");
		Outer.Inter2 oi2=new Outer.Inter2();
		oi2.show();
		oi2.show1();//静态方法
		System.out.println("------------");
		//另一种访问show1
		Outer.Inter2.show1();
	}

}
结论:对于静态内部类,要想访问外部类成员变量,该成员变量都要被static修饰.

局部内部类:
对于局部内部类的访问:创建外部类对象,用外部类对象调用外部类成员方法.

局部内部类访问局部变量时,局部变量需要被final修饰,由于局部变量是随着方法调用生成的,随着方法的调用完毕消失,而现在局部位置有一个局部内部类要在自己的成员方法

位置调用局部变量,则把局部变量变成一个常量.

相关代码:

class Outer{
	//成员变量
	public int num=10;
	//成员方法
	public void method(){
		//局部变量
		final int num1=20;
		//局部位置
		class Inner{
			//局部内部类成员方法
			public void show(){
				System.out.println(num);
				System.out.println(num1);
			}
		}
		Inner i=new Inner();
		i.show();
	}
}
public class InnerDemo {
	public static void main(String[] args) {
		//对于局部内部类访问时调用外部类成员方法,因此创建外部类对象,调用该方法.
		Outer o=new Outer();
		o.method();
	}

}
匿名内部类:

相关代码:

interface Inter1{
	public abstract void study() ;
}

class StudentDemo{
	public void method(Inter1 i){//形式参数是一个接口
		i.study() ;
	}
}
public class OuterTest {
	public static void main(String[] args) {
		//需求:调用StudentDemo中的method()方法
		StudentDemo sd = new StudentDemo() ;
		sd.method(new Inter1(){

			@Override
			public void study() {
				System.out.println("好好学习,天天向上...");
			}
			
		}) ;
		
	}
}
面试题:
按照要求,补齐代码
interface Inter { void show(); }
class Outer { //补齐代码 }
class OuterDemo {
public static void main(String[] args) {
Outer.method().show();
}
}
要求在控制台输出”HelloWorld”

代码:

interface Inter1{
	public abstract void show();
}
class  Outer1{
	public static Inter1 method(){//返回值是一个接口
		return new Inter1(){

			@Override
			public void show() {
				System.out.println("HelloWorld");
			}
			
		};
	}
}
public class OuterDemo {
	public static void main(String[] args) {
		Outer1.method().show();
		
	}
}
分析:当前method()能直接被Outer调用,则该方法是静态的;Outer.method().show()->Outer.method()返回的是一个对象,所以用对象调用show()方法.另外重写show方法.

七.形式参数和返回值.

形式参数:

基本类型:要什么数据类型,在实际传参的时候就传什么数据类型.

引用类型:

具体类:需要创建具体对象.

抽象类:需要自定义一个抽象类的子类,抽象类多态进行实例化.

接口:需要自定义一个接口的子类,接口多态进行实例化.

相关代码:

class person{
	public void show(){
		System.out.println("I love you");
	}
}
class personDemo{
	public void method(person p){//形式参数引用具体类
		p.show();
	}
	public void method1(person1 p1){//形式参数引用抽象类
		p1.show();
	}
	public void method2(person2 p2){//形式参数引用接口
		p2.show();
	}
}
abstract class person1{
	public abstract void show();
}
class person1Demo extends person1{
	@Override
	public void show() {
		System.out.println("you love me");
	}
}
interface person2{
	public abstract void show();
}
class person2Demo implements person2{
	@Override
	public void show() {
		System.out.println("那就结婚吧!");
	}
	
}
public class PersonDemo {
	public static void main(String[] args) {
		personDemo pd=new personDemo();//创建对象,调用method()
		person p=new person();
		pd.method(p);//形参是具体类
		System.out.println("----------");
		person1 p1=new person1Demo();
		pd.method1(p1);//形参是抽象类
		System.out.println("----------");
		person2 p2=new person2Demo();//形参是接口
		pd.method2(p2);
	}
}

返回值类型:

基本类型

应用类型:

具体类:直接返回该类对象.(通常使用匿名对象)

抽象类:返回该抽象类的子对象.

接口:返回该接口的子对象.

相关代码:

class person{
	public void show(){
		System.out.println("I love you");
	}
}
class personDemo{
	public person method(){//返回值引用具体类
		return new person();
	}
	public person1 method1(){//返回值引用抽象类
		return new person1Demo();
	}
	public person2 method2(){
		return new person2Demo();//返回值引用接口
		
	}
}
abstract class person1{
	public abstract void show();
}
class person1Demo extends person1{
	@Override
	public void show() {
		System.out.println("you love me");
	}
}
interface person2{
	public abstract void show();
}
class person2Demo implements person2{
	@Override
	public void show() {
		System.out.println("那就结婚吧!");
	}

	
}
public class PersonDemo {
	public static void main(String[] args) {
		personDemo pd=new personDemo();//创建对象,调用method()
		person p=pd.method();
		p.show();//返回值是具体类
		System.out.println("----------");
		person1 p1=pd.method1();
		p1.show();//返回值是抽象类
		System.out.println("----------");
		person2 p2=pd.method2();
		p2.show();//返回值是接口
		
		//链式编程
		person2 p3=new personDemo().method2();
		p3.show();
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值