六、七章 复习

2.1介绍类与对象

          在现实世界中,随处可见的一种事物就是对象,对象是事物存在的实体,如人类、书桌、计算机、高楼大厦等。人类解决问题的方式总是将复杂的事物简单化,于是就会思考这些对象都是由哪些部分组成的。通常都会将对象划分为两个部分,即静态部分与动态部分。静态部分,顾名思义,就是不能动的部分,这个部分被称为“属性”,任何对象都具备其自身属性,如一个人,其属性包括高矮、胖瘦、性别、年龄等。然而具有这些属性的人会执行哪些动作也是一个值得探讨的部分,这个人可以哭泣、微笑、说话、行走,这些是这个人具备的行为(动态部分),人类通过探讨对象的属性和观察对象的行为了解对象。

2.2 类

类就是同一类事物的统称,如果将现实世界中的一个事物抽象成对象,类就是这类对象的统称,如鸟类、家禽类、人类等。类是构造对象时所依赖的的规范,如一只鸟具有一对翅膀,它可以用这对翅膀飞行,而基本上所有的鸟都具有翅膀这个特性和和飞行的技能,这样具有相同特性和行为的一类事物就称为类,类的思想就是这样产生的。类是封装对象的属性和行为载体,具有相同属性和行为的一类实体被称为类。

2.3面向对象程序设计具有以下特点:

        封装性。继承性。多态性。

1.封装
        封装是面向对象编程的核心思想。将对象的属性和行为封装起来,其载体就是类,类通常对客户隐藏其实现细节,这就是封装的思想。例如,用户使用计算机时,只需要使用手指敲击键盘就可以实现一些功能,无须知道计算机内部是如何工作的,即使可能知道计算机的工作原理,但在使用计算机时也并不完全依赖于计算机工作原理这些细节。
采用封装的思想保证了类内部数据结构的完整性,应用该类的用户不能轻易地直接操作此数据结构,只能执行类允许公开的数据。这样就避免了外部操作对内部数据的影响,提高了程序的可维护性。 

2.继承

继承性主要利用特定对象之间的共有属性。

3.多态

        将父类对象应用于子类的特征就是多态,多态的实现并不依赖具体类,而且抽象类和接口。

2.4 类与对象

       2.4.1 成员变量
        在Java中对象的属性也称为成员变量,成员变量的定义与普通变量的定义一样。

语法如下:

数据类型    变量名称[=值];

其中,[ = 值]表示可选内容,即定义变量时可以为其赋值,也可以不为其赋值。 

2.4.2成员方法
1.成员方法的定义
        定义成员方法的语法格式如下:

[权限修饰符]【返回值类型]方法名(  [参数类型参数名 ] ) [throws异常类型]{
 
        …        //方法体
 
        return 返回值; 

                }

        其中,“权限修饰符”可以是private、public、protected中的任一个,也可以不写,主要用来控制方法的访问权限,关于权限修饰符将在下一章中详细讲解;“返回值类型”指定方法返回数据的类型,可以是任何类型,如果方法不需要返回值,则使用 void关键字;一个成员方法既可以有参数,
也可以没有参数,参数可以是对象也可以是基本数据类型的变量

代码如下:

public void showGoods() {
System.out.println("库存商品名称:");
 System.out.println(FullName); 
                        }
 

2.成员方法的参数
调用方法时可以给该方法传递一个或多个值,传给方法的值叫做实参,在方法内部,接收实参的变量叫做形参,形参的声明语法与变量的声明语法一样。形参只在方法内部有效。Java 中方法的参数主要有3种,分别为值参数、引用参数和不定长参数.
(1)值参数
        值参数表明实参与形参之间按值传递,当使用值参数的方法被调用时,编译器为形参分配存储单元,然后将对应的实参的值复制到形参中,由于是值类型的传递方式,所以,在方法中对值类型的形参的修改并不会影响实参。

示例代码:

	public class Can {	
		private int add(int x,int y){			//计算两个数的和
			x=x+y;//对x进行加y操作
			return x;//返回x
									}
									
			public static void main(String[] args) {//主方法
				Can book=new Can();//创建Book对象
				int x=30;//定义实参变量x
				int y=40;//定义实参变量y
				System.out.println("运行结果:"+book.add(x,y));//输出运行结果
				System.out.println("实参x的值:"+x);//输出实参x的值
				}
					 }
				

(2)引用参数
        如果在给方法传递参数时,参数的类型是数组或者其他引用类型,那么,在方法中对参数的修改会反映到原有的数组或者甘他引用米刑上.这种类型的方法参数,我们称之为引用参数。

示例代码:

zpublic class RefTest {//类名
 
	public static void main(String[] args) {        //主方法
		RefTest refTest=new RefTest();            //创建RefTest对象
		int[]i={0,1,2};                        //定义一维数组,作为方法的实参
		System.out.print("原始数据:");            //输出内容
		for(int j=0;j<i.length;j++){/        /遍历数组
			System.out.print(i[j]+" ");        //输出数组元素
		}
 refTest.change(i);                    //调用方法改变数组元素的值
 System.out.print("\n修改后的数据:");        //输出信息
 for(int j=0;j<i.length;j++){                //遍历数组
	 System.out.print(i[j]+" ");            //输出数组元素
 }
	}
public void change(int[]i){//给数组赋值的方法
	i[0]=100;/                    /给数组与元素赋值
	i[1]=200;                    //给数组与元素赋值
	i[2]=300;                    //给数组与元素赋值
}
}

(3)不定长参数

声明方法时,如果有n个相同类型的参数,可以定义为不定长参数,该类型的参数声明如下:

权限修饰符  返回值类型 方法名(参数类型   参数名称)

示例代码:

	public class Can {	
			public static void main(String[] args) {					//主方法
				Can multi=new Can();									//创建对象
				System.out.print("运算结果:"+multi.add(20,30,40,50,60));//输出信息并调用计算总和方法
												  }
			int add(int...x){										//定义add方法,并指定不定长参数的类型为int
						int result=0;								//定义一个整型变量
						for(int i=0;i<x.length;i++){				//遍历数组
							result+=x[i];							//将数组中元素的值相加
												}
				return result;										//返回运算结果
							}
					}
							
					
				

 

2.5构造方法
        在类中除了成员方法之外,还存在一种特殊类型的方法,那就是构造方法。构造方法是一个与类同名的方法,对象的创建就是通过构造方法完成的。每当类实例化一个对象时,类都会自动调用构造方法。
构造方法的特点如下:


(1)构造方法没有返回类型,也不能定义为 void.

(2)构造方法的名称要与本类的名称相同。
{3)构造方法的主要作用是完成对象的初始化工作,它能把定义对象的参数传给对象成员


        在定义构造方法时,构造方法没有返回值,但这与普通没有返回值的方法不同,普通没有返回值的方法使 public void methodEx()这种形式进行定义,但构造方法并不需要使用 void关键字进行修饰。
构造方法的定义语法如下:

class Book {
public Book() {         //构造方法 
              }
        
 
 
Public:构造方法修饰符。 
Book:构造方法的名称。

        在构造方法中可以为成员变量赋值,这样当实例化一个本类的对象时,相应的成员变量也将始化。如果类中没有明确定义构造方法,则编译器会自动创建一个不带参数的默认构造方法。
除此之外,在类中定义构造方法时,还可以为其添加一个或者多个参数,即有参数构造方法

语法如下:

class Book{
public Book(int args) { //有参数构造方法 
//对成员变量进行初始化
                       }
          }
public:构造方法修饰符

Book:构造方法的名称。
args:构造方法的参数,可以是多个参数。

注意:

        如果在类中定义的构造方法都是有参构造方法,则编译器不会为类自动生成一个默认的无参构造方法,当试调用无参构造方法实例化一个对象时,编译器会报错。所以只有在类中没有定义任何构造方法时,编译器才在该类中自动创建一个不带参数的构造方法。
        构造方法除了可以用public修饰以外,还可以用private修饰,即私有的构造方法,私有构造法无法使用new创建对象,这时需要使用静态方法生成类的对象。

示例代码:

	public class Can {	
			private Can()
			{												//私有构造方法
			}												//静态公开方法,向图书馆借书
			static public  Can libraryBorrow()
			{												//创建静态方法,返回本类实例对象
				System.out.println("通过调用静态方法创建对象");			//输出信息
				return new Can();								//返回本类实例对象
			}
			public static void main(String[] args) {			//主方法
				Can book=Can.libraryBorrow();					//创建一个书的对象,不是new实例化的,而是通过方法从图书馆借来的
													}
					}
			
 
				

 

2.6对象的销毁

每个对象都有生命的周期,当对象的生命周期结束时,分配给该对象的内存地址会被回收。在其它语言中需要手动回收废弃的对象,但在Java拥有一套完整的垃圾回收机制,用户不必担心废弃的对象占用内存,垃圾回收站将回收无用的但占用内存的资源。何种对象会被Java虚拟机视为垃圾。

(1)对象引用超出其作用范围,这个对象将被视为垃圾

(2)将对象赋值为null。

finalize()方法可进行垃圾回收但不一定会发生

System.gc()方法强制启动垃圾回收器。 

2.7 this关键字

        this引用的就是本类的一个对象,在局部变量或方法参数覆盖了成员变量时如果省略this关键字直接写成name=name,那只是把参数name赋值给参数变量本身而已员变量name的值没有改变,因为参数name在方法的作用域中覆盖了成员变量name,this 除了可以调用成员变量或成员方法之外,还可以作为方法的返回值。

代码如下:

	public class Can {					//创建Can类
			String name="abc";			//定义一个成员变量
			public void showName(String name)
			{												//定义一个showName类并从传入一个参数
				System.out.println(name);					//输出
			}
				public static void main(String[] args) {
					Can book=new Can();					//在Book2类定义一个对象
					book.showName("123");					//调用showName方法
													  }
			 
			}
					
				
			
 

2.8static关键字

        由static修饰的变量、常量和方法被称作静态变量、静态常量和静态方法,也被称为类的静态成员。静态成员是属于类所有的,区别于个别对象。

2.9 静态变量,常量,方法
   

语法如下:

static  a ;   // 静态变量

final static A;  //静态常量

  static public void  b(){        //静态方法

}

3.0类的封装

封装是面向对象编程的核心思想,将对象的属性和行为封装起来。其载体就是类。

无封装代码如下:

public class Restaurant1 {//创建一个类
 
	public static void main(String[] args) {//主方法
		String cookName="Tom Cruise";//厨师的名字叫Tom Cruise
		System.out.println("**请让厨师为我做一份香辣肉丝。***");//输出
		System.out.println(cookName+"切葱花");//输出
		System.out.println(cookName+"洗蔬菜");//输出
		System.out.println(cookName+"开始烹饪"+"香辣肉丝");//输出
		System.out.println("**请问厨师叫什么名字?***");//输出
		System.out.println(cookName);//输出
		System.out.println("请让厨师给我切一点葱花。***");//输出
		System.out.println(cookName+"切葱花");//输出
	}
 
}

封装成类代码如下:

public class Restaurant2 {//创建一个类
 
	public static void main(String[] args) {//主方法
		Cook1 cook=new Cook1();//创建厨师类的对象
		System.out.println("**请让厨师为我做一份香辣肉丝。***");//输出
		cook.cooking("香辣肉丝");//厨师烹饪香辣肉丝
		System.out.println("**你们的厨师叫什么名字?***");//输出
		System.out.println(cook.name);//厨师回答自己的名字
		System.out.println("**请让厨师给我切一点葱花。***");//输出
		cook.cutOnion();//厨师去切葱花
 
	}
 
}
class Cook1{//创建类
	String name;//厨师的名字
	public Cook1(){//定义一个方法
		this.name="Tom Cruise";//厨师的名字叫Tom Cruise
	}
	void cutOnion(){//厨师切葱花
		System.out.println(name+"切葱花");//输出信息
	}
	void washVegetables(){//厨师洗蔬菜
		System.out.println(name+"洗蔬菜");//输出信息
	}
	void cooking(String dish){//厨师烹饪顾客点的菜
		washVegetables();//调用洗蔬菜方法
		cutOnion();//调用切葱花方法
		System.out.println(name+"开始烹饪"+dish);//输出信息
	}
}

 使用private修饰代码如下:

public class Restaurant4 {//创建类
private Cook2 cook=new Cook2();//餐厅封装的厨师类
public void takeOlder(String dish){//下单	Restaurant2 a=new Restaurant2();//创建一个对象
	cook.cooking(dish);//通知厨师做菜
	System.out.println("您的菜好了,请慢用。");//输出信息
}
public String saySorry(){//拒绝顾客请求
	return"抱歉,餐厅不提供此项服务。";//返回字符串
	
}
	public static void main(String[] args) {//主方法
		Restaurant4 water=new Restaurant4();//创建餐厅对象,为顾客提供服务
		System.out.println("**请让厨师为我做一份香辣肉丝。***");//输出
		water.takeOlder("香辣肉丝");//服务员给顾客下单
		System.out.println("**你们的厨师叫什么名字?***");//输出信息
		System.out.println(water.saySorry());//服务员给顾客善意的答复
		System.out.println("**请让厨师给我切一点葱花。***");//输出信息
		System.out.println(water.saySorry());//服务员给顾客善意的答复
	}
 
}

3.1类的继承

        继承在面向对象开发思想中是一个非常重要的概念,它使整个程序架构具有一定的弹性,在程序中复用已经定义完善的类不仅可以减少软件开发周期,还可以提高软件的可维护性和可扩展性。其基本思想是基于某个父类的扩展,制定出一个新的子类,子类可以继承父类原有的属性和方法,也可以增加原来父类所不具备的属性和方法,或者直接重写父类中的某些方法。例如,平行四边形是特殊的四边形,可以说平行四边形类继承了四边形类,这时平行四边形类将所有四边形具有的属性和方法都保留下来,并基于四边形类扩展了一些新的平行四边形类特有的属性和方法。

 3.2extends 关键字

让一个类继承另一个类,用extends关键字,语法如下:

child  extends parents             

child: 子类

parents:父类

extends:继承关键字

class Computer{//父类
	String screen="液晶显示屏";
	void startup(){//开机方法
		System.out.println("电脑正在开机,请等待...");//输出
	}
}
 
public class Pad extends Computer{//创建一个类并继承父类
String battery="5000毫安电池";//子类独有的属性
	public static void main(String[] args) {//主方法
		Computer pc=new Computer();//电脑类
		System.out.println("computer的屏幕是:"+pc.screen);//输出
		pc.startup();//调用父类方法
		Pad ipad=new Pad();//平板电脑类
		System.out.println("pad的屏幕是:"+ipad.screen);//子类可以直接使用父类属性
		System.out.println("pad的屏幕是:"+ipad.battery);//子类独有的属性
		ipad.startup();//子类可以直接使用父类方法
 
	}
 
}

 3.2方法的重写
  1.重写的实现 
        继承并不只是扩展父类的功能,还可以重写父类的成员方法。重写(还可以称为覆盖)就是类中将父类的成员方法的名称保留,重新编写成员方法的实现内容,更改成员方法的存储权限,可修改成员方法的返回值类型。

示例代码:

class Computer2{//父类:电脑
	void showPicture(){//定义一个方法
		System.out.println("鼠标单击");//输出信息
	}
}
public class Pad2 extends Computer2 {//创建一个类并继承父类
void showPicture(){//重写父类的方法
	System.out.println("手指点击触摸屏");//输出信息
}
	public static void main(String[] args) {//主方法
		Computer2 pc=new Computer2();//电脑类
		System.out.print("pc打开图片:");//输出信息
		pc.showPicture();//调用方法
		Pad2 ipad=new Pad2();//平板电脑类
		System.out.print("ipad打开图片:");//输出信息
		ipad.showPicture();//重写父类方法
		Computer2 computerpad=new Pad2();//父类声明,子类实现
		System.out.print("computerpad打开图片:");//输出信息
		computerpad.showPicture();//调用父类方法,实现子类重写的逻辑
	}
 
}

3.3所有类的父类--Object类
        使用 class关键字定义类时,就应用了继承原理,因或间接继承了java.lang.Object类。Object类是比较特殊的类,它是所有类的父类,是 Java 类层中的最高层类。当创建一个类 class时,总是在继承,除非某个类已经指定要从其他类继承,否则它就是从java.lang.Object类继承而来的,可见Java中的每个类都源于java.lang.Object类,如String、Integer等类都是继承于Object类;除此之外自定义的类也都继承于Object类。由于所有class类都是Object子类,所以在定义类时,省略了 extends Object关键字,在Object类中主要包括cloneO、finalizeequals、toString0等方法,其中常用的两个方法为equals()和toString0方法。由于所有的类都是Object类的子类,所以任何类都可以重写 Object类中的方法。 

1.getClass()方法
        getClass()方法是Object类定义的方法,它会返回对象执行时的 Class实例,然后使用此例用getName()方法可以取得类的名称。
语法如下:

getclass().getName();

可以将getClass()方法与toString()方法联合使用。
2. toString()方法
        toString0方法的功能是将一个对象返回为字符串形式,它会返回一个 String实例。在实际的营用中通常重写toString0)方法,为对象提供一个特定的输出模式。当这个类转换为字符串或与字符甲连接时,将自动调用重写的 toString()方法。

示例代码:

		public class Can {//创建类
			public String toString(){//重写toString()方法
				return "在"+getClass().getName()+"类中重写toString()方法";//返回值
			}
				public static void main(String[] args) {//主方法
					System.out.println(new Can());//调用方法并输出,打印本类对象
				}
			 
			}

3.equals()方法
        equals()方法,是比较“==”运算符与equals()方法,说明”==”比是两个对象的引用是否相等,而equals0方法比较的是两个对象的实际内容。

示例代码:

		public class Can {//创建类
			 
				public static void main(String[] args) {//主方法
					String s1="123";//实例化两个对象,内容相同
					String s2="123";//实例化对象
					System.out.println(s1.equals(s2));//使用equals()方法
					Can v1= new Can();//实例化两个类对象
					Can v2=new Can();//实例化对象
					System.out.println(v1.equals(v2));//使用equals()方法
				}
			 
			}

3.4类的多态
        多态意为一个名字可具有多种语义,在程序设计语言中,多态性是指“一种定义,多种实现”例如,运算符“+”作用于两个整型量时是求和,而作用于两个字符型量时则是将其连接在一起。用多态可以使程序具有良好的扩展性,并可以对所有类对象进行通用的处理。类的多态性可以从两方面体现:一是方法的重载,二是类的上下转型
3.4.1 方法的重载
        我们知道构造方法的名称由类名决定,所以构造方法只有一个名称,但如果希望以不同的方式来实例化对象,就需要使用多个构造方法来完成。由于这些构造方法都需要根据类名进行命名,为了让方法名相同而形参不同的构造方法同时存在,必须用到“方法重载”虽然方法重载起源于构造方法,但是它也可以应用到其他方法中。
        方法的重载就是在同一个类中允许同时存在一个以上的同名方法,只要这些方法的参数个数或类型不同就可。
示例代码:

		public class Can {//创建类
				public static int add(int a){//定义一个方法并传入一个int型参数
					return a;//返回一个整型值
				}
				public static int add(int a,int b){//定义一个方法并传入两个参数
					return a+b;//返回a+b的值
				}
				public static double add(double a,double b){//定义一个方法并传入两个参数
					return a+b;//返回a+b的值
				}
				public static int add(int a,double b){//定义一个方法并传入两个参数
					return (int)(a+b);//返回a+b的值,同时利用强制转换成int型
				}
				public static int add(double a,int b){//定义一个方法并传入两个参数
					return (int)(a+b);//返回a+b的值,同时利用强制转换成int型
				}
				public static int add(int...a){//定义一个不定长参数方法
					int s=0;//定义一个int型变量并赋予初值
					for(int i=0;i<a.length;i++){//遍历数组
						s+=a[i];//总计
					}
					return s;//返回s的值
				}
				public static void main(String[] args) {//主方法
					System.out.println("调用add(int)方法:"+add(1));//调用方法并输出
					System.out.println("调用add(int,int)方法:"+add(1,2));//调用方法并输出
					System.out.println("调用add(double,double)方法:"+add(2.1,3.3));//调用方法并输出
					System.out.println("调用add(int a,double b)方法:"+add(1,3.3));//调用方法并输出
					System.out.println("调用add(double a,int b)方法:"+add(2.1,3));//调用方法并输出
					System.out.println("调用add(int...a)不定长参数方法:"+add(1,2,3,4,5,6,7,8,9));//调用方法并输出
					System.out.println("调用add(int...a)不定长参数方法:"+add(2,3,4 ));//调用方法并输出
			 
				}
			
				}

3.4.2 向上转型

子类转变成父类类型

示例代码:

class Quadrangle{//四边形类
public static void draw(Quadrangle q){//四边形类中的方法
//SomeSentence
                       }
}
public class Parallelogram extends Quadrangle{//平行四边形类,继承了四边形类
public static void main(String args[]){//主方法
Parallelogram p=new Parallelogram();//实例化平行四边形类对象引用
draw(p);//调用父类方法
            }
}

 3.4.3 向下转型

父类转变成子类 使用强制转换

代码如下:

class Quadrangle{//父类
	public static void draw(Quadrangle q){//父类方法
		//SomeSentence
	}
}
public class Parallelogram extends Quadrangle {//子类继承父类
 
	public static void main(String[] args) {//主方法
	draw(new Parallelogram());//调用方法并传入子类对象
	Quadrangle q=new Parallelogram();//将平行四边形对象看作是四边形对象,称为向上转型操作
	Parallelogram p=q;//向下转型
 
	}
 
}

3.5 instanceof关键字
        当在程序中执行向下转型操作时,如果父类对象不是子类对象的实例,就会发生CastException 异常,所以在执行向下转型之前需要养成一个良好的习惯,就是判断父类对象是否子类对象的实例。这个判断通常使用instanceof操作符来完成。可以使用instanceof操作符判断是一个类实现了某个接口(接口会在74节中进行介绍),也可以用它来判断一个实例对象是否属于个类。
instanceof的语法格式如下:

myobject instanceof ExampleClass
myobject:某类的对象引用。

ExampleClass:某个类。

        使用instanceof操作符的表达式返回值为布尔值。如果返回值为true,说明myobject 对象ExampleClass 的实例对象;如果返回的值为false,说明myobject对象不是ExampleClass的实例对象。

代码如下:

class Quadrangle{//类名
	public static void draw(Quadrangle q){//构造一个方法并传入一个参数
		//SomeSentence
	}
}
class Square extends Quadrangle{//构造一个类并继承另一个类
	//SomeSentence
}
class Anything{//构造一个类
	//SomeSentence
}
public class Parallelogram extends Quadrangle {//创建一个类并继承另一个类
 
	public static void main(String[] args) {//主方法
		Quadrangle q=new Quadrangle();//创建一个对象
		if(q instanceof Parallelogram){//判断该对象是否属于该类
			Parallelogram p=(Parallelogram)q;//进行强制转换
		}
		if(q instanceof  Square){//判断该对象是否属于该类
			Square s=(Square) q;//进行强制转换
		}
		System.out.println(q instanceof  Anything );//输出信息
	}
 
}

3.6 抽象类与接口

3.6.1抽象类与抽象方法
        在解决实际问题时,一般将父类定义为抽象类,需要使用这个父类进行继承与多态处理。回提继承和多态原理,继承树中越是在上方的类越抽象,如鸽子类继承鸟类、鸟类继承动物类等。在多态机制中,并不需要将父类初始化对象,我们需要的只是子类对象,所以在 Java 语言中设置抽象不可以实例化对象,因为图形类不能抽象出任何一种具体图形,但它的子类却可以。
        Java中定义抽象类时,需要使用abstract关键字,其语法如下:

[权限修饰符] abstract class 类名 {
类体
                                }

使用abstract关键字定义的类称为抽象类,而使用abstract关键字定义的方法称为抽象方法,抽象方法的定义语法如下:

[权限修饰符] abstract 方法返回值类型 方法名 (参数列表);

示例代码:

public abstract class Market {//创建类
public String name;//商场名称
public String goods;//商品名称
public abstract void shop();//抽象方法,用来输出信息
}

 

public class TaobaoMarket extends Market {//创建类并继承商场类
 
	@Override
	public void shop() {//重写方法
		// TODO Auto-generated method stub
		System.out.println(name+"网购"+goods);	//输出信息	
	}
 
}
public class GoShopping {//类名
 
	public static void main(String[] args) {//主方法
		// TODO Auto-generated method stub
Market market=new WallMarket();//向上转型
market.name="沃尔玛";//赋值
market.goods="七匹狼西服";//赋值
market.shop();//调用方法
market=new TaobaoMarket();//创建一个对象
market.name="淘宝";//赋值
market.goods="韩都衣舍花裙";//赋值
market.shop();//调用方法
	}
 
}

  综上所述,使用抽象类和抽象方法时,需要遵循以 下原则: 
(1)在抽象类中,可以包含抽象方法,也可以不包已含抽象方法,但是包含了抽象方法的类必须被定义为抽象类。
(2)抽象类不能直接实例化,即使抽象类中没有声 明抽象方法,也不能实例化。 
(3)抽象类被继承后,子类需要实现其中所有的抽象方法。
(4)如果继承抽象类的子类也被声明为抽象类,则可以不用实现父类中所有的抽象方法。使用抽象类时,可能会出现这样的问题:程序中会有太多冗余的代码,同时这样的父类局限生很大,例如,上面的例子中,也许某个不需要 shop()方法的子类也必须重写shopO方法。如果将这个shopO方法从父类中拿出,放在别的类里,又会出现新问题,就是某些类想要实现“买衣服”的场景,竟然需要继承两个父类。Java 中规定,类不能同时继承多个父类,面临这种问题时,接口的概念便出现了。

3.7接口的声明及实现
接口是抽象类的延伸,可以将它看作是纯粹的抽象类,接口中的所有方法都没有方法体。

接口使用interface 关键字进行定义,语法如下:

[ 修饰符 ] interface 接口名 [ extends 父接口名列表 ] {
 
    [public] [static] [final] 常量;
    [public] [abstract] 方法;
                                                    }
修饰符:可选,用于指定接口的访问权限,可选值为 public。如果省略则使用默认的访权限。
接口名:必选参数,用于指定接口的名称,接口名必须是合法的 Java标识符。一般情况下要求首字母大写。

extends父接口名列表:可选参数,用于指定要定义的接口继承
于哪个父接口。当使用extends关键字时,父接口名为必选参数。方法:接口方法定义而没有被实现。

一个类实现一个接口可以使用implements关键字,代码如下:

 
public class Parallelogram extends Quadrangle implements drawTest{
 
…//
    }

 

3.8区分抽象类与接口
        抽象类和接口都包含可以由子类继承实现的成员,但抽象类是对根源的抽象,而接口是对动作的抽象。抽象类的功能要远超过接口,那为什么还要使用接口呢?这主要是由于定义抽象类的代价高(因为每个类只能继承一个类,在这个类中,必须继承或编写出其子类的所有共性,因此,虽然接口在功能上会弱化许多,但它只是针对一个动作的描述,而且可以在一个类中同时实现多个接口,这样会降低设计阶段的难度。
抽象类和接口的区别主要有以下几点。
注意:


(1)子类只能继承一个抽象类,但可以实现任意多个接口。
声明类时,如果不使用p
(2)一个类要实现一个接口必须实现接口中的所有方法,而抽象类不必。
(3)抽象类中的成员变量可以是各种类型,而接口中的成员变量只能是public static finalf
口多学两招:
Java语言中,类的权限
(4)接口中只能定义抽象方法,而抽象类中可以定义非抽象方法。
定义一个public的doSt
(5)抽象类中可以有静态方法和静态代码块等,接口中不可以。
下面两段代码是等效的
(6)接口不能被实例化,没有构造方法,但抽象类可以有构造方法。

3.9访问控制

3.9.1 访问控制符

        前面介绍了面向对象的几个基本特性,其中包括封装性,封装实际上有两方面的含义:把谈藏的隐藏起来、把该暴露的暴露出来,这两个方面都需要通过使用Java提供的“访问控制符”来现,Java中的访问控制符主要包括public、protected、private和default(缺省)等4种,这些控育符控制着类和类的成员变量以及成员方法的访问权限。

使用访问控制符时,需要遵循以下原则。

(1)大部分顶级类都使用public修饰;
(2)如果某个类主要用作其他类的父类,该类中包含的大部分方法只是希望被其子类重写。而不想被外界直接调用,则应该使用protected修饰;
(3)类中的绝大部分属性都应该使用private修饰,除非一些static或者类似全局变量的属性,才考虑使用public 修饰;
(4)当定义的方法只是用于辅助实现该类的其他方法(即工具方法),应该使用private修饰;(5)希望允许其他类自由调用的方法应该使用public修饰。


3.9.2 Java 类包
        在Java中每定义好一个类,通过Java编译器进行编译之后,都会生成一个扩展名为class的文件,当这个程序的规模逐渐庞大时,就很容易发生类名称冲突的现象。那么JDK API中提供了成千上万具有各种功能的类,Java中提供了一种管理类文件的机制,就是类包。Java中每个接口或类都来自不同的类包,无论是JavaAPI中的类与接口还是自定义的类与接口都需要隶属于某一个类包,这个类包包含了一些类和接口。如果没有包的存在,管理程序中的类名称将是一件非常麻烦的事情,如果程序只由一个类定义组成,并不会给程序带来什么影响,但是险着程序代码的增多,难免会出现类同名的问题。例如,在程序中定义一个Login类,因业务需要,还要定义一个名称为Login 的类,但是这两个类所实现的功能完全不同,于是问题就产生了,编译器不会允许存在同名的类文件。解决这类问题的办法是将这两个类放置在不同的类包中,实际上 ava中类的完整名称是包名与类名的组合。

在类中定义包名的语法如下:
package包名1[.包名2[.包名3...]];

        在上面的语法中。包名可以设置多个,包名和包名之间使用.分割,包名的个数没有限制,其中前面的包名包含后面的包名。
在类中指定包名时需要将package放置在程序的第一行,它必须是文件中的第一行非注释代码当使用package关键字为类指定包名之后,包名会成为类名中的一部分,预示着这个类必须指定全名。

4.0  成员内部类

 在一个类使用内部类,可以在内部类中直接存取其所在类的私有成员变量。

     语法如下:

public class OuterClass{            //外部类
     private class  InnerClass    {    //内部类
        //...
    }       
}

        在内部类中可以随意使用外部类的成员方法以及成员变量,尽管这些成员被修饰为private .

        内部类的实例一定要绑定在外部类的实例上,如果从外部类中初始化一个内部类对象。那么内部类对象就会绑定在外部类对象上。内部类初始化方式与其他初始化方式相同,都是使用new 关键字。

示例代码:

public class OuterClass {//创建类
innerClass in=new innerClass();//创建对象
public void ouf(){//方法
	
}
class innerClass{//类名
	innerClass(){//方法
		
	}
	public void inf(){//方法
	}
	int y=0;//定义变量
	}
	public innerClass doit(){//方法
		//y=4;
		in.y=4;//调用变量
		return new innerClass();//返回对象
	}
 
	public static void main(String[] args) {//主方法
		OuterClass out=new OuterClass();//创建对象
		OuterClass.innerClass in=out.doit();//调用方法
		OuterClass.innerClass in2=out.new innerClass();//向上转型
 
	}
 
}

4.1静态内部类

在内部类前添加修饰符static,这个内部类就变为静态内部类了,一个静态内部类可以声明静态成员,但是在非静态内部类中不可以声明静态成员。静态内部类有一个最大的特点,就是不能用外部类的非静态成员,所以静态内部类在程序开发中比较少见。
可以这样认为,普通的内部类对象隐式地在外部保存了一个引用,指向创建它的外部类对象但如果内部类被定义为static,就会有更多的限制。

静态内部类具有以下两个特点:

(1)如果创建静态内部类的对象,不需要创建其外部类的对象;

(2)不能从静态内部类的对象中访问非静态外部类的对象。

示例代码:

public class StaticInnerClass {//创建类
	int x=100;//定义一个整型变量并初始化
	static class Inner{//内部类
	void doitInner(){//方法
	//System. out. printin("外部类"+x);//输出
	}
	public static void main(String args[]){//主方法
	
	
	System. out. println();//换行
	}
}
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值