JAVA OOP

1.类和对象的创建

public class 类和对象的创建 {
	public static void main(String[] args) {
		//2、创建Person类的对象
	Person p1=new Person();
	//Scanner scanner=new Scanner(System.in);

	//调用对象的结构:属性、方法
	//调用属性:“对象.属性”
	p1.name="Tom";
	p1.isMale=true;
	System.out.println(p1.name);	
	//调用方法:“对象.方法”
	p1.eat();
	p1.sleep();
	p1.talk("Chease");

//--------------------------------------------------------------------------------------------
	Person p2=new Person();
	System.out.println(p2.name);//Tom? null?报错?
	System.out.println(p2.isMale);
//将怕变量保存的对象地址赋值给p3,导致p1和p3指向了堆空间的同一个对象实体			
	Person p3=p1;
	System.out.println(p3.name);//Tom
	
	p3.age=10;
	System.out.println(p1.age);//10
	}
}
//1、创建类、设计类的成员
class Person{
	//属性
	String name;
	int age;
	boolean isMale;
	//方法
	public void eat() {
		System.out.println("吃饭");
	}
	public void sleep() {
		System.out.println("睡觉");
	}
	public void talk(String language) {
		System.out.println("说话");
	}
}

2.匿名对象的使用

package javaOOP;
/*
 * 匿名对象
 * 1、理解:我们创建的对象,没有显示的赋给一个变量名,即为匿名对象
 * 2、特征:匿名对象只能调用一次
 * 3、使用:
 */
public class 匿名对象的使用 {
public static void main(String[] args) {
	Phone p=new Phone();
	System.out.println(p);
	p.sendEmail();
	p.playGame();
	
	//匿名对象
//	new Phone().sendEmail();
//	new Phone().playGame();
	
	new Phone().price=1999;
	new Phone().showPrice();//0.0
//--------------------------------------------------------
	PhoneMall mall=new PhoneMall();
	mall.show(new Phone());
}
}

class PhoneMall{
	public void show(Phone phone) {
		phone.sendEmail();
		//匿名对象的使用
		phone.playGame();
	}
}

class Phone{
	double price;
	public void sendEmail() {
		System.out.println("发送邮件");
	}
	public void playGame() {a
		System.out.println("玩游戏");
	}
	public void showPrice() {
		System.out.println("手机价格为"+price);
	}
}
面向对象程序设计的重点是类的设计
  * 一、设计类就是设计类的成员。
    *  属性=成员变量=field=域、字段
       方法=成员方法=函数=method
     *  创建类的对象=类的实例化=实例化类
     *  
     *  二、类和对象的使用(面向对象思想落地实现)
     *  (1)创建类,设计类的成员
     *  (2)创建类的对象
     *  (3)通过“对象.属性”或“对象.方法”调用对象结构
     *  
     *  三、如果创建了一个类的多个对象,则每个对象都独立的拥有一套类的属性(非static的)
     *  意味着:如果我们修改一个对象的属性a,则不影响另外一个对象属性a的值
     *  
     *  4、对象的创建和使用:内存解析
     *  堆:存放对象实例
     *  栈:存储局部变量
     *  方法区:存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据
        */

3.方法的使用与声明

public class 方法的使用与声明 {
      public static void main(String[] args) {
    	  Customer cust1=new Customer();
    	  cust1.eat();
      }
}
//客户类
class Customer{
	//属性
	String name;
	int age;
	boolean isMale;
    
	//方法
	public void eat() {
		System.out.println("客户吃顿饭");
	}
	public void sleep(int hour) {
		System.out.println("休息了"+hour+"个小时");
	}
	public String getName(){
		return name;
	}
	public String getNation(String nation) {
		return nation;
	}
}
类中方法的声明和使用
 * 方法:描述类应该具有的功能
 * 比如:Math类,sqrt()\random()
 * Scanner类:nextXxx()...
 * Arrays类:sort()\binarySearch()\toString()\.....
 * 
 * 1、举例
 * public void eat() {}              //无返回值
 * public void sleep(int hour) {}    //无返回值
 * public String getName(){}         //返回字符串
 * public String getNation() {}      //返回字符串
 * 
 * 2、方法的声明:权限修饰符 返回值类型 方法名(形参列表){
 * 方法体;
 * }
 * static\final\abstract\来修饰方法,后面讲
   *
 * 3、说明
 * 3.1关于权限修饰符:
 * Java规定的4种权限权限修饰符:private、public、缺省、protected
 * 3.2返回值类型:有返回值 vs 无返回值
 * 3.2.1如果方法有返回值,则必须在方法声明时,指定返回值的类型。同时方法中,需要使用return关键字来返回指定类型的变量或常量。
 * 如果方法没有返回值,则方法声明,使用void来表示。通常没有返回值的方法中,就不需要return。或者return;
 * 3.3.2我们定义方法该不该有返回值?
 * (1)看题目要求
 * (2)
 * 3.3方法名:属于标识符,遵循标识符的规则和规范:"见名知意"
 * 3.4形参列表:方法可以声明0个、1个或多个形参
 * 3.4.1格式:数据类型1 形参1,数据类型2 形参2,....
 * 3.4.2我们定义方法时,该不该定义形参?
 * (1)题目要求
 * (2)凭经验
 * 3.5方法体:方法功能的体现。

 

4.属性的使用

public class 属性的使用 {
	public static void main(String[] args) {
		User u1=new User();
		System.out.println(u1.name);
		System.out.println(u1.age);
		System.out.println(u1.isMale);
		
		u1.talk("日语");
		u1.eat();
	}
}
class User{
	//属性(或局部变量)
	String name;
	int age;
	boolean isMale;
	
	public void talk(String language) {//language:形参,也是局部变量
		System.out.println("我们使用"+language+"进行交流");
	}
	public void eat() {
		String food="烙饼";//局部变量
		System.out.println("北方人喜欢吃"+food);
	}
}
类中属性的使用
 * 属性(成员变量)vs 局部变量
 * 一、相同点
 * 1.1定义变量的格式相同:数据类型 变量名=变量值
 * 1.2先声明,后使用
 * 1.3变量都有其对应的作用域
 * 
 * 二、不同点
 * 2.1在类中声明的位置不同
 * 属性:直接定义在类的一对{}内
 * 局部变量:声明在方法内、方法形参、代码块内、构造器形参、构造器内的部的变量
 * 2.2关于权限修饰符的不同
 * 属性:可以在声明属性时,指明其权限,使用权限修饰符
 * 常用的权限修饰符:private、public、缺省、protected--->封装性
 * 目前,声明属性时,都是以缺省
 * 局部变量(方法里):不可以使用权限修饰符
 * 2.3默认初始化值的情况:
 * 属性:类的属性,根据其类型,都有默认初始化值
 * 整型(byte、short、int、long):0
 * 浮点型(float、double):0.0
 * 字符型(char):0或'\u0000'
 * 布尔型(boolean):false
 * 
 * 局部变量:没有默认的初始化值。所以,在调用局部变量之前,一定要显式赋值
 * 特别的:形参在调用时,我们赋值即可
 * 2.4在内存中加载的位置:
 * 属性:加载到堆空间(非static)
 * 局部变量:加载到栈空间

5.方法的重载

package javaOOP;
/*
 * 方法的重载(overload)
 * 1.重载的概念:
 * 在同一个类中,允许存在一个以上的同名方法,只要它们的参数个数或参数类型不同即可
 * 2.重载的特点:
 * 与返回值类型无关,只看参数列表,且参数列表必须不同。(参数个数或参数类型)。调用时,根据方法参数列表的不同来    区别
 * 3.判断是否重载:
 * 跟方法的权限修饰符,返回值类型,形参变量名,方法体都没有关系
 * 4.在调用方法时,如何确定某一个指定的方法,
 * 方法名------>参数列表
 */

public class OverLoadTest {
	public static void main(String[] args) {
		OverLoadTest test=new OverLoadTest();
		test.getSum(1,2);
	}
public void getSum(int i,int j) {
	System.out.println("1");
}
public void getSum(double d1,double d2) {
	System.out.println("2");
}
public void getSum(String s,int i) {
	System.out.println("3");
}
public void getSum(int i,String s) {
	System.out.println("4");
}
//public int getSum(int i,int j) {
//	return 0;
//}
//public void getSum(int m,int n) {
//	
//}
//private void getSum(int i,int j) {
//	return 0;
//}
}

6.可变个数形参的方法

package javaOOP;
/*
 * 可变个数形参的方法
 * 1、JDK5.0新增内容
 * 2、具体使用
 *    2.1可变个数形参的格式:数据类型...变量名
 *    2.2当调用可变个数形参的方法时,传入的参数个数可以是:0个,1个,...
 *    2.3可变个数形参的方法与本类中方法名相同,形参不同的方法之间构成重载
 *    2.4可变个数形参的方法与本类中方法名相同,形参类型也相同的数组之间不构成重载,二者不能共存
 *    2.5可变个数形参在方法的形参中,必须声明在末尾
 *    2.6可变个数形参在方法的形参中,最多只能声明一个可变形参
 */
public class MethodArgsTest {
	public static void main(String[] args) {
		MethodArgsTest test=new MethodArgsTest();
		test.show(12);
		test.show("hello");
	}
	public void show(int i) {
		
	}
	public void show(String s) {
		System.out.println("show(String)");
	}
	public void show(String...strs) {
		System.out.println("show(sTring...strs)");
	}   
//	public void show(String[] strs) {
//		
//	}   编译器认为这种方式和上面那一种是一样的,这两个方法不可共存

//    public void show(String...strs,int i) {
//    	这样写错误,不能把可变个数String...strs放在前面
//    }
}

7.关于变量的赋值

package javaOOP;
/*
 * 关于变量的赋值:
 * 如果变量为基本数据类型,此时赋值的是变量所包存的数据值
 * 如果变量是引用数据类型,此时赋值的是变量所保存的数据的地址值
 */
public class ValueTransferTest {
public static void main(String[] args) {
	int m=10;
	int n=m;
	System.out.println("m="+m+",n="+n);
	n=20;
	System.out.println("m="+m+",n="+n);
System.out.println("-----------引用数据类型---------------------------------------------");
	
    Order o1=new Order();
	o1.orderId=1001;
	
	Order o2=o1;//赋值以后o1和o2的地址值相同,都指向了堆空间中同一个对象实体
	System.out.println("o1.orderId="+o1.orderId+",o2.orderId="+o2.orderId);
	o2.orderId=1002;
	System.out.println("o1.orderId="+o1.orderId+",o2.orderId="+o2.orderId);
}
}
class Order{
	int orderId;
}

8.方法形参的传递机制:值传递

package javaOOP;
/*
 * 方法形参的传递机制:值传递
 * 1.形参:方法定义时,声明的小括号内的参数
 *   实参:方法调用时,实际传递给形参的数据
 * 2.值传递机制:
 *   如果参数为基本数据类型,此时实参赋给形参的是实参真实存储的数据值
 *   如果参数是引用数据类型,此时赋值的是变量所保存的数据的地址值。
 */
public class ValueTransferTest1 {
	public static void main(String[] args) {
		int m=10;
		int n=20;
		System.out.println("m="+m+",n="+n);
		//交换两个变量的值的操作
//		int temp=m;
//		m=n;
//		n=temp;
		
		ValueTransferTest1 test1=new ValueTransferTest1();
		test1.swap(m, n);
		System.out.println("m="+m+",n="+n);
	}
public void swap(int m,int n) {
	int temp=m;
	m=n;
	n=temp;
}
}
-----------------------------------------------------------------------------------------------------
    package javaOOP;

public class ValueTransferTest2 {
	public static void main(String[] args) {
		Data data=new Data();
		data.m=10;
		data.n=20;
		System.out.println("m="+data.m+",n="+data.n);
		//交换m和n的值
//		int temp=data.m;
//		data.m=data.n;
//		data.n=data.temp;
		
	
		ValueTransferTest2 test=new ValueTransferTest2();
		test.swap(data);
		
		System.out.println("m="+data.m+",n="+data.n);
		
	}
	public void swap(Data data) {
		int temp=data.m;
		data.m=data.n;
		data.n=data.temp;
	}
}
class Data{
	int m;
	int n;
	int temp;
}

9.递归方法的使用

 

package javaOOP;
/*

 * 递归方法的使用(了解)
 * 一个方法体内调用它自身
 * 方法的递归包含了一种隐式循环,它会重复执行某段代码,但这种重复执行无须循环控制
 * 递归一定要向已知方向递归,否则这种递归就变成了无穷递归,类似于死循环
   */
   public class RecursionTest {
   public static void main(String[] args) {
   //例1:计算1-100之间所有自然数的和
   	//方式一做法
   	int sum=0;
   	for(int i=1;i<=100;i++) {
   		sum +=i;
   	System.out.println(sum);
   	}
   	RecursionTest test=new RecursionTest();
   	int sum1=test.getSum(100);
   	System.out.println(sum1);
   }
      //方式二
   public int getSum(int n){
   	if(n==1) {
   		return 1;
   	}else {
   		return n+getSum(n-1);
   	}
   }
   }

10.封装与隐藏

package 封装与隐藏;
/*
 * 面向对象的特征一:封装与隐藏
 * 一 、问题的引入
 * 当我们创建一个类的对象以后,我们可以通过“对象.属性”的方式,对对象的属性进行赋值。这里,赋值操作要受到
 * 属性的数据类型和存储范围的制约,除此之外没有其他制约条件。
 * 但是,在实际问题中,我们往往需要给属性赋值加入额外的限制条件。
 * 这个条件就不能在属性声明时体现。我们只能通过方法进行限制条件的添加(比如setLegs())
 * 同时,我们需要避免用户再使用“对象.属性”的方式对属性进行赋值。则需要将属性声明为私有的(private)
 * --->此时针对属性就体现了封装性
 
 * 二、封装性的体现
 * 我们将类的属性私有化(private),同时,提供公共的(public)方法来获取(getxxx)和设置(setxxx)此属性的值
 * 封装性的体现:1、如上 2、不对外暴露的私有的方法 3、单例模式...
 
 * 三、封装性的体现需要权限修饰符来配合
 * 1、Java规定的4种权限(从小到大排列)private、缺省、protected、public
 * 2、4种权限可以用来修饰类及类的内部结构:属性、方法、构造器、内部类
 * 3、具体的,4种权限都可以用来修饰类的内部结构:属性、方法、构造器、内部类
 * 修饰类大的话,只能使用:缺省、public
 *总结:Java提供了4种权限修饰符来修饰类及类的内部结构,体现类及类的内部结构在被调用时的可见性
 */

   public class AnimalTest {
   public static void main(String[] args) {
   	Animal  a =new Animal();
   	        a.name="大黄";
   //		a.age=1;
   //		a.legs=4;
   	         a.show();
   	

//		a.legs=-4;
//		a.setLegs(6);
		a.setLegs(-6);
		a.show();
		System.out.println(a.name);
	}
}
class Animal{
	String name;
	private int age;
	private int legs;//私有,上面无法调用了,
	
	//对属性的设置
	public void setLegs(int l) {
		if(l>=0&&l%2==0) {
			legs=l;
		}else {
			legs=0;//对legs进行一个封装,无法直接调用,可通过接口调用,通过setLegs
		}
	}
	
	//对属性的获取
	public int getLegs() {
		return legs;
	}
	
	public void eat() {
		System.out.println("动物进食");
	}
	public void show() {
		System.out.println("name="+name+",age="+age+",legs="+legs);
	}
	
	//提供关于属性age的get和set方法
	public int getAge() {
		return age;
	}
	public void setAge(int a) {
		age=a;
	}

}
package 封装与隐藏;
public class Person {
private int age;
public void setAge(int a) {
	if(a<0||a>130) {
		System.out.println("传入的数据非法");
		return;
	}
	age=a;
}
public int getAge() {
	return age;
}

//绝对不要这样写
//public int doAge(int a) {
//	age=a;
//	return age;
//}
}
//===================================================================================================
package 封装与隐藏;
public class PersonTest {
public static void main(String[] args) {
	Person p1=new Person();
//	p1.age=1; 编译不通过
	
	p1.setAge(12);
	System.out.println("年龄为"+p1.getAge());
}
}
package 封装与隐藏;
public class Order {
	private int orderprivate;
	int orderDefault;
	public int orderPublic;
	
	private void methodprivate() {
		orderprivate=1;
		orderDefault=2;
		orderPublic=3;
	}
	void methoddefault() {
		orderprivate=1;
		orderDefault=2;
		orderPublic=3;
	}
	public void methodpublic() {
		orderprivate=1;
		orderDefault=2;
		orderPublic=3;
	}
}
//=================================================================================================
package 封装与隐藏;
public class OrderTest {
public static void main(String[] args) {
	Order order=new Order();
	order.orderDefault=1;
	order.orderPublic=2;
	//出了Order类之后(或者出了Order类所属的包之后),私有的结构不可以调用
//	order.orderprivate=3;      //The field Order.orderprivate is not 
	
	order.methoddefault();
	order.methodpublic();
	//出了Order类之后,私有结构不可调用
//	order.methodprivate();    //The method methodprivate() from the type Order is not visible
}
}

11.构造器

package 构造器;
/*
 * 类的结构之三:构造器(构造方法:constructor)的使用
 * 一、构造器的作用:
 * 1.创建对象
 * 2.初始化对象的属性
 * 
 * 二、说明
 * 1.如果没有显示的定义类的构造器的话,则系统默认提供一个空参的构造器
 * 2.定义构造器的格式:权限修饰符 类名(形参列表)
 * 3.一个类中定义的多个构造器,彼此重载
 * 4.一旦我们显式的定义了类的构造器之后,系统就不再提供默认的空参构造器
 * 5.一个类中至少要有一个构造器
 */
public class PersonTest {
     public static void main(String[] args) {
	//创建类的对象:new+构造器
	Person person=new Person();
	person.eat();
	
	Person p1=new Person("Tom");
	System.out.println(p1.name);
}
}
class Person{
	//属性
	String name;
	int age;
	
	//构造器     
	public Person() {
		System.out.println("person()...");
	}
	
	public Person(String n) {
		name=n;
	}
	
	public Person(String n,int a) {
		name=n;
		age=a;
	}
	
	//方法
	public void eat() {
		System.out.println("人吃饭");
	}
	public void study() {
		System.out.println("人可以学习");
	}
}
package 构造器;
/*
 * 编写两个类,TriAngle和TriAngleTest,其中TriAngle类中声明私有的底边长base和高height,
 * 同时声明公共方法访问私有变量,此外,提供类必要的构造器。另一个类中使用这些公共方法,计算三角形面积
 */
public class TriAngle {
	private double base;
	private double height;
	
	public TriAngle() {
		
	}
	public TriAngle(double b,double h) {
		base=b;
		height=h;
	}
	
	public void setBase(double b) {
		base =b;
	}
	public double getBase() {
		return base;
	}
	public void setHeight(double h) {
		height=h;
	}
	public double getHeight() {
		return height;
	}
}
//===================================================================================================
package 构造器;
public class TriAngleTest {
public static void main(String[] args) {
	TriAngle t1=new TriAngle();
	t1.setBase(2.0);
	t1.setHeight(2.4);
//	t1.base=2.5   The field TriAngle.base is not visible
//	t1.height=4.3
	System.out.println("base"+t1.getBase()+"height"+t1.getHeight());
	
	//调一个带参的,构造器一方面可以用来创造对象,同时也可以进行一个赋值操作
	TriAngle t2=new TriAngle(5.1,5.6);
	System.out.println("base:"+t2.getBase()+"height:"+t2.getHeight());
}
}

12.JavaBean

package javaBean;
/*
 * javaBean是一种Java语言写成的可重用组件
 * JavaBean,是指符合如下标准的Java类
 *  >类是公共的
 *  >有一个无参的公共的构造器
 *  >有属性,且有对应的get、set方法
 */
public class Customer {
	private int id;
	private String name;
	
	public Customer() {
	//提供空参构造器	
	}
	public void setId(int i) {
		id=i;
	}
	public int getId(){
		return id;
	}
	public void setName(String n) {
		name=n;
	}
	public String getName() {
		return name;
	}
}

 

13.关键字:this的使用

package this关键字;
/*
 * this关键字的使用
 * 1.可以用来修饰、调用:属性、方法、构造器
 * 2.this修饰属性和方法
 *   this理解为:当前对象 或 当前正在创建的对象
 *   在类的方法(构造器)中,我们可以使用"this.属性"或"this.方法"的方式,调用当前对象属性或方法。
 *   但是,通常情况下,我们都选择省略"this."。特殊情况下,如果方法(构造器)的形参和类的属性同名时,我们必须显式
 *   的使用"this.变量"的方式,表明此变量是属性,而非形参
 * 3.this调用构造器
 * ①我们在类的构造器中,可以显式的使用"this(形参列表)"方式,调用本类中指定的其他构造器
 * ②构造器中不能通过"this(形参列表)"方式,调用自己
 * ③如果一个类中有n个构造器,最多有n-1构造器中使用"this(形参列表)"
 * ④规定:"this(形参列表)"必须声明在当前构造器的首行
 * ⑤构造器内部, 最多只能声明一个this(形参列表)
 * 
 */
public class PersonTest {
	public static void main(String[] args) {
		Person p1=new Person();
		p1.setAge(1);
		System.out.println(p1.getAge() );
		p1.eat();
	}
}
class Person{
	private String name;
	private int age;
	
	public void setName(String name) {
//		name=name;
		this.name=name;
	}
	public String getName() {
		return name;
	}
	public void setAge(int age) {
//		age=age; 属性跟形参重名了
		this.age=age;//当前对象的age(.后面不是属性就是方法)
	}
	public int getAge() {
		return age;
	}
//==========================================
	public void eat() {
		System.out.println("人吃饭");
//		study();或者this.study
		this.study();  //方法中再调方法,这里的this是p1
	}
	public  void study() {
		System.out.println("人学习");
	}
}
package javaExample;
public class Account {
	//属性
	private int id;//账号
	private double balance;//余额
	private double annualInterestRate;//年利率
	//构造器
	public Account(int id, double balance, double annualInterestRate) {
		this.id = id;
		this.balance = balance;
		this.annualInterestRate = annualInterestRate;
	}
	//方法
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public double getBalance() {
		return balance;
	}
	public void setBalance(double balance) {
		this.balance = balance;
	}
	public double getAnnualInterestRate() {
		return annualInterestRate;
	}
	public void setAnnualInterestRate(double annualInterestRate) {
		this.annualInterestRate = annualInterestRate;
	}
	public void withdraw(double amount) {//取钱
		if(balance<amount) {
			System.out.println("余额不足,取款失败");
			return;
		}
		balance-=amount;
		System.out.println("成功取出"+amount);
	}
	public void deposit(double amount) {//存钱
		if(amount>0) {
			balance+=amount;
			System.out.println("成功存入"+amount);
		}
	}
}
//==================================================================================================
package javaExample;
public class Customer {
	private String firstName;
	private String lastName;
	private Account account;
	
	public Customer(String f,String l) {
		this.firstName=f;
		this.lastName=l;
	}
	public Account getAccount() {
		return account;
	}
	public void setAccount(Account account) {
		this.account=account;
	}
	public String getLastName() {
		return lastName;
	}
	public String getfirstName(){
		return firstName;
	}
}
//===================================================================================================
package javaExample;
/*
 * 写一个程序
 * (1)创建一个customer,名字叫Jane Smith,
 * 他有一个账号为1000,余额2000元,年利率1.23%的账户
 * (2)对Jane Smith操作
 * 存入100元,再取出960元。再取出2000元
 * 打印出Jane Smith的基本信息
 * 
 * 成功存入:100.0
 * 成功取出:960
 * 余额不足,取款失败
 * Customer[Smith,Jane] has a account:id is 1000,annualInterestRate is
 */
public class CustomerTest {
	public static void main(String[] args) {
		Customer cust=new Customer("Jane","Smith");
		Account acct=new Account(1000, 2000, 0.0123);
		
		cust.setAccount(acct);
		cust.getAccount().deposit(100);
		cust.getAccount().withdraw(960);
		cust.getAccount().withdraw(2000);
		System.out.println("Customer["+cust.getLastName()+","
		+cust.getfirstName()+"count: id is"+ cust.getAccount().getId()
		+",annualInterestRate is"+cust.getAccount().getAnnualInterestRate()*100
		+"%,balance is"+cust.getAccount().getBalance());
	}
}

14.package关键字的使用

/*
 * 一、package关键字的使用
 * 1.为了更好的实现项目中类的管理,提供包的概念
 * 2.使用package声明类或者接口所属的包,声明在源文件首行
 * 3.包,属于标识符,遵循标识符的命名规范、“见名知意”
 * 4.每"."一次,就代表一层文件目录
 * 补充:同一个包下,不能命名同名的接口、类。
 * 不同的包下,可以命名同名的接口、类。
 *  
 * 二、import关键字的使用
 * import:导入
 * 1.在源文件中显式的使用import结构导入指定包下的类、接口
 * 2.声明在包的声明和类的声明之间
 * 3.如果需要导入多个结构,则并列写出即可
 * 4.可以使用"xxx.*"的方式,表示可以导入xxx包下的所有结构
 * 5.如果使用的类或接口是java.lang包下定义的,则可以省略import结构
 * 6.如果使用的类或接口是本包下的同名的类,则必须至少有一个
 * 7.如果在源文件中,使用了不同包下的同名的类, 则必须至少有一个类需要以全类名的方式显示
 * 8.使用"xxx.*"方式表明可以调用xxx包下的所有结构,但是如果使用的是xxx子包下的结构,则仍需要显式导入
 * 9.import static:导入指定类或接口中的静态结构:属性或方法
   */

15.eclipse常用快捷键

/*
 * 1.补全代码的声明:alt + /
 * 2.快速修复:ctrl + 1
 * 3.批量导包:ctrl + shift + o
 * 4.使用单行注释:ctrl + /
 * 5.使用多行注释:ctrl + shift + /
 *   取消多行注释:ctrl + shift + \
 * 6.复制指定行的代码:ctrl + alt + down 或 ctrl + alt +up
 * 7.删除指定行代码:ctrl + d
 * 8.上下移动代码:alt + up 或 alt + down
 * 9.切换到下一行代码空位:shift + enter
 * 10.切换到上一行代码空位:ctrl + shift + enter
 * 11.如何查看源代码:ctrl + 选中指定的结构 或 ctrl + shift + t
 * 12.退回到前一个编辑的页面:alt + left
 * 13.进入到下一个编辑的页面:alt + right
 * 14.光标选中指定的类,查看继承树结构:ctrl + t
 * 15.格式化代码:ctrl + shift + f
 * 16.选中数行,整体往后移动:tab
 * 17.选中数行,整体往前移动:shift + tab
 * 18.在当前类中,显示类的结构,并支持搜索指定的方法、属性等:ctrl + o
 * 19.批量修改指定的变量名、方法名、类名等:alt + shift + r
 * 20.显示当前getter/setter/构造器等结构:alt + shift + s
 * 21.显示当前选择资源(工程or文件)的属性:alt + enter
 * 22:选中的结构大小写切换:变大写:ctrl + shift + x
 *                         变小写:ctrl + shift + y
 * 23.快速查找:参照选中的Word快速定位到下一个:ctrl + k
 * 24.关闭当前窗口:ctrl + w
 * 25.关闭所有窗口:ctrl + shift + w
 * 26.查看指定的结构使用过的地方:ctrl + alt + g
 * 27.查找与替换:ctrl + f  
 * 28.最大化当前的View:ctrl + m
 * 29.直接定位到当前行的首位:home
 * 30.直接定位到当前行的末位:end
 */

16.面向对象之继承性

 

package 面向对象之继承性;
public class Creature {
	public void breath() {
		System.out.println("呼吸");
	}
}
//===============================================================================================
package 面向对象之继承性;
public class Person extends Creature {
   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 sleep() {
		System.out.println("睡觉");
	}
}
//================================================================================================
package 面向对象之继承性;
public class Student extends Person {
//	String name;
//	int age;
	String major;

	public Student() {
		
	}
	
	public  Student(String name,int age,String major){
		this.name=name;
		this.age=age;
		this.major=major;
	}
//	public void eat() {
//		System.out.println("吃饭");
//	}
//	public void sleep() {
//		System.out.println("睡觉");
//	}
	public void study() {
		System.out.println("学习");
	}
	public void show() {
		System.out.println("name"+ name+"age"+age);
	}
}
//==================================================================================================
package 面向对象之继承性;
/*
 * 面向对象的特征之二:继承性
 * 一、继承性的好处
 * ①:减少代码的冗余,提高代码的复用性
 * ②:便于功能的扩展
 * ③:为之后的多态性的使用,提供了前提
 * 
 * 二、继承性的格式  class A extends B {}
 *     A:子类(派生类)、subclass
 *     B:父类、超类、基类、superclass
 *     体现:一旦子类A继承父类B以后,子类A中就获取了父类B中声明的所有的结构、属性、方法
 *     特别的,父类中声明为private的属性或方法,子类继承父类以后,仍然认为获取了父类中私有的结构
 *     只因为 封装性的影响,使得子类不能直接调用父类的结构而已
 *     子类继承父类以后,还可以声明自己特有的方法。子类与父类的关系哦不同于集合和子集的关系,子类的功能要高于父类
 * 
 * 三、Java中关于继承的规定
 * ①、一个类可以被多个子类继承
 * ②、一个类只能有一个父类:单继承
 * ③、子类是相对概念
 * ④、子类继承父类以后,就获取了直接父类以及所有间接父类中声明的属性和方法
 * 四、
 * 1.如果我们没有显式的声明一个类的父类的话,则此类继承于java.lang.Object
 * 2.所有的java类(除java.lang.Object类之外)都直接或间接的继承于java.lang.Object类
 * 3.意味着所有的java类具有java.lang.Object类声明的功能
 */
public class ExtendsTest {
	public static void main(String[] args) {
		Person p1=new Person();
		p1.age=1;
		p1.eat();
		 
		Student s1=new Student();
		s1.age=3;
		s1.eat();
		s1.sleep();
		s1.name="Tom";
		s1.breath();
	}
}

 

继承练习题
package 练习2;
/*
 * 定义一个ManKind类,包括成员变量int sex和int salary
 * 方法void manOrWoman():根据sex的值显示"man"(sex==1)或者"woman"(sex==0);
 * 方法 void employeed():根据salary的值显示"no job"(salary==0)或者"job"(salary!=0)
 */
public class ManKind {
	//属性
	private int sex;
	private int salary;
	//一个空的构造器
	public ManKind() {
		
	}
	//构造器
	public ManKind(int sex, int salary) {
		this.sex = sex;
		this.salary = salary;
	}
	//方法
	public void manOrWoman() {
		if(sex==1) {
			System.out.println("man");
		}else if(sex==0) {
			System.out.println("Woman");
		}
	}
	public void employeed() {
		if(salary==0) {
			System.out.println("no job");
		}else {
			System.out.println("job");
		}
	}
	//或
//	String jobInfo=(salary==0)?"no job":"job";
//	System.out.println(jobInfo);
	public int getSex() {
		return sex;
	}
	public void setSex(int sex) {
		this.sex = sex;
	}
	public int getSalary() {
		return salary;
	}
	public void setSalary(int salary) {
		this.salary = salary;
	}
}
//===================================================================================================
package 练习2;
/*
 * 定义Kinds继承ManKind并包括成员变量int,yearsold:
 * 方法printAge()打印yearsold的值
 */
public class Kids extends ManKind{
	//属性
	private int yearsold;
	//无参的构造器
	public Kids() {
		
	}
	//构造器
	public Kids(int yearsold) {
		
		this.yearsold = yearsold;
	}
	//get set 方法
	public int getYearsold() {
		return yearsold;
	}
	public void setYearsold(int yearsold) {
		this.yearsold = yearsold;
	}
    //打印输出
	public void printAge() {
		System.out.println("I am"+yearsold+"yearsold");
	}
}
//===================================================================================================
package 练习2;
/*
 * 定义KidTest,在类的main方法中实例化Kids的对象someKid,
 * 用该对象访问其父类的成员变量及方法
 */
public class KidsTest {
	public static void main(String[] args) {
		Kids someKid=new Kids(12);
		someKid.printAge();
		
		someKid.setSalary(0);
		someKid.setSex(1);
		someKid.employeed();
		someKid.manOrWoman();
	}
}
package 练习3;
public class Circle {
	private double radius;
	public Circle () {
		radius=1.0;
	}
	public double getRadius() {
		return radius;
	}
	
	public void setRadius(double radius) {
		this.radius = radius;
	}
	
	public double findArea() {
		return Math.PI*radius*radius;
	}
	
}
//===================================================================================================
package 练习3;
public class Cylinder extends Circle {
	private double length;
	public Cylinder() {
		length=1.0;
	}
	
	public double getLength() {
		return length;
	}
	public void setLength(double length) {
		this.length = length;
	}
	
	//返回圆柱的体积
	public double findVolume() {
		return Math.PI*getRadius()*getLength();
		//或 return findArea()*getLength();
	}
}
//===================================================================================================
package 练习3;
public class CylinderTest {
	public static void main(String[] args) {
		Cylinder cy=new Cylinder();
		cy.setRadius(2.1);
		cy.setLength(3.4);
		double volume=cy.findVolume();
		System.out.println("圆柱的体积为"+volume);
		
		double area=cy.findArea();
		System.out.println("底面圆的面积:"+area);
	}
}

17.方法的重写

package 方法的重写;
public 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(int distance) {
		System.out.println("走路,走的距离是:"+distance+"公里");
	}
	
	private void show() {
		System.out.println("我是一个人");
	}
}
//==================================================================================================
package 方法的重写;
public class Student extends Person{
	String major;
	public Student() {
		
	}
	public Student(String major) {
		this.major=major;
	}
	public void study() {
		System.out.println("学习,专业是"+major);
	}
	//重写了父类中的eat方法
	public void eat() {
		System.out.println("学生应该多吃有营养的食物");
	}
	private void show() {
		System.out.println("我是一个学生");
	}
}
//=================================================================================================
package 方法的重写;
/*
 * 方法的重写(override/overwrite)
 * 1.重写:子类继承父类以后,可以对父类中同名同参数的方法,进行覆盖
 * 2.应用:重写以后,当创建子类对象以后,通过子类对象调用子父类对象中的同名同参数的方法时,实际执行的是子类重写父类的方法
 * 3.重写的规定:
 *            方法的声明:权限修饰符 返回值类型 方法名(形参列表){
 *            //方法体
 *            }
 *            约定:子类中的叫重写的方法,父类中的叫被重写的方法
 *            ①子类重写的方法的方法名和形参列表与父类被重写的方法的方法名和形参列表相同
 *            ②子类重写的方法的权限修饰符不小于父类被重写的方法的权限修饰符
 *                >特殊情况:子类不能重写父类中声明为private的方法
 *            ③返回值类型:
 *                >父类被重写的方法的返回值类型是void,则子类重写的方法的返回值类型只能是void
 *                >父类被重写的方法的返回值类型是A类型,则子类重写的返回值类型可以是A类或A类的子类
 *                >父类被重写的方法的返回值类型是基本数据类型,则子类重写的返回值类型必须是基本数据类型
 *            ④子类重写的方法抛出的异常类型不大于父类被重写的方法抛出的异常类型 
 *            
 *            子类和父类同名同参数的方法要么都声明为非static的,要么都声明为static的(不是重写)
 * 区分方法的重载与重写
 */
public class PersonTest {
public static void main(String[] args) {
	Student s=new Student("计算机科学与技术");
	s.eat();
	s.walk(10);
	s.study();
}
}
package 重写练习题1;
/*
 * 定义Kinds继承ManKind并包括成员变量int,yearsold:
 * 方法printAge()打印yearsold的值
 */
public class Kids extends ManKind {
	//属性
		private int yearsold;
		//无参的构造器
		public Kids() {
			
		}
		//构造器
		public Kids(int yearsold) {
			
			this.yearsold = yearsold;
		}
		//get set 方法
		public int getYearsold() {
			return yearsold;
		}
		public void setYearsold(int yearsold) {
			this.yearsold = yearsold;
		}
		
	    //打印输出
		public void printAge() {
			System.out.println("I am"+yearsold+"yearsold");
		}
/*
 * 修改练习中定义的类kids,在kids中重新定义employeed()方法,
 * 覆盖父类ManKind中定义的employeed()方法
 * 输出"Kids should study and no job"
 */
		public void employeed() {
			System.out.println("Kids should study and no job");
		}
		
}
//===================================================================================================
package 重写练习题1;
/*
 * 定义一个ManKind类,包括成员变量int sex和int salary
 * 方法void manOrWoman():根据sex的值显示"man"(sex==1)或者"woman"(sex==0);
 * 方法 void employeed():根据salary的值显示"no job"(salary==0)或者"job"(salary!=0)
 */
public class ManKind {
	//属性
		private int sex;
		private int salary;
		//一个空的构造器
		public ManKind() {
			
		}
		//构造器
		public ManKind(int sex, int salary) {
			this.sex = sex;
			this.salary = salary;
		}
		//方法
		public void manOrWoman() {
			if(sex==1) {
				System.out.println("man");
			}else if(sex==0) {
				System.out.println("Woman");
			}
		}
		public void employeed() {
			if(salary==0) {
				System.out.println("no job");
			}else {
				System.out.println("job");
			}
		}
		//或
//		String jobInfo=(salary==0)?"no job":"job";
//		System.out.println(jobInfo);
		public int getSex() {
			return sex;
		}
		public void setSex(int sex) {
			this.sex = sex;
		}
		public int getSalary() {
			return salary;
		}
		public void setSalary(int salary) {
			this.salary = salary;
		}
}
//==================================================================================================
package 重写练习题1;
/*
 * 定义KidTest,在类的main方法中实例化Kids的对象someKid,
 * 用该对象访问其父类的成员变量及方法
 */
public class KidsTest {
	public static void main(String[] args) {
		Kids someKid=new Kids(12);
		someKid.printAge(); 
		
		someKid.setSalary(0);
		someKid.setSex(1);
		someKid.manOrWoman();
		someKid.employeed();
	}
}

18.super关键字

package super关键字;
public class Person {
	String name;
	int age;
	int id=1001;
	public Person(){
		
	}
	public Person(String namString) {
		this.name=name;
	}
	public Person(String name,int age) {
	    this(name);
		this.age=age;
	}
	public void eat() {
		System.out.println("人,吃饭");
	}
	public void walk() {
		System.out.println("人走了");
	}
}
//=================================================================================================
package super关键字;
public class Student extends Person {
	String major;
	int id=1002;
	public Student() {
		
	}
	public Student(String najor) {
		this.major=major;
	}
	public Student(String name,int age,String major) {
//		this.name=name;
//		this.age=age;
		super(name,age);
		this.major =major;
	
		
	}
	public void eat() {
		System.out.println("学生吃有营养的食物");
	}
	public void study() {
		System.out.println("好好学习,天天向上");
		this.eat();
		super.eat();
		this.walk();
	}
	public void show() {
		System.out.println("name"+this.name+"age"+age);
		System.out.println("id="+id);//省略的是this.id   1002
		System.out.println("id="+super.id);//1001  子父类中出现同名的属性,为了去区分需要显示的使用super.来表示调用的父类的属性
	}
	
}
//===================================================================================================
package super关键字;
/*
 * super关键字的使用
 * 1.super理解为:父类的
 * 2.super可以用来调用:属性、方法、构造器
 * 3.super的使用
 *   ①我们可以在子类的方法或构造器中。通过使用"super.属性"或"super.方法"的方式,
 *   显式的调用父类中声明的属性或方法,但是,通常情况下,习惯性省略"super."
 *   ②特殊:当子类和父类中定义了同名的属性时,我们要想在子类中调用父类中声明的属性
 *   则必须显式的使用"super.属性"的方式,表明调用的是父类中声明的属性
 *   ③特殊:当子类重写了父类中的方法以后,我们想在子类的方法中调用父类中被重写的方法时
 *   使用"super.方法"的方式,表明调用的是父类的方法
 * 4.super调用构造器
 *   ①我们可以在子类的构造器中显式的使用"super(形参列表)"的方式,调用父类声明的指定的构造器
 *   ②"super(形参列表)"的使用,必须声明在子类构造器的首行
 *   ③我们在类的构造器中,针对于"this(形参列表)"或"super(形参列表)"
 *   ④在构造器首行,没有显式的声明"this(形参列表)"或"super(形参列表)",则默认调用的是父类中空参的构造器
 *   ⑤在类的多个构造器中,至少有一个类的构造器中使用了"super(形参列表)"调用父类的构造器
 */
public class SuperTest {
	public static void main(String[] args) {
		Student s=new Student();
		s.show();
		s.study();
		
		Student s1=new Student("Tom",21,"IT");
		s1.show();
	}
}
package 继承和super课后练习;
public class Account {
	private int id;//账号
	private double balance;//余额
	private double annualInterestRate;//年利率
	public Account(int id, double balance, double annualInterestRate) {
		super();
		this.id = id;
		this.balance = balance;
		this.annualInterestRate = annualInterestRate;
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public double getBalance() {
		return balance;
	}
	public void setBalance(double balance) {
		this.balance = balance;
	}
	public double getAnnualInterestRate() {
		return annualInterestRate;
	}
	public void setAnnualInterestRate(double annualInterestRate) {
		this.annualInterestRate = annualInterestRate;
	}
	//返回月利率
	public double getMonthlyInterest() {
		return annualInterestRate/12;
	}
	//取钱
	public void withdraw(double amount) {
		if(balance>=amount) {
			balance-=amount;
			return;
		}
		System.out.println("余额不足");
	}
	//存钱
	public void deposit(double amount) {
		if(amount>0) {
			balance += amount;
		}
	}
}
//===================================================================================================
package 继承和super课后练习;
/*
 * 写一个用户程序测试Account类,在用户程序中,
 * 创建一个账号为1122、余额为20000、年利率为4.5%的Account对象
 * 使用withdraw方法提款30000元,并打印余额
 * 再使用withdraw方法提款2500元
 * 使用deposit方法存款3000元,然后打印余额和月利率
 */
public class AccountTest {
	public static void main(String[] args) {
		Account acct=new Account(1122, 20000, 0.045);
		acct.withdraw(30000);
		System.out.println("您的账户余额为:"+acct.getBalance());
		acct.withdraw(2500);
		System.out.println("您的账户余额为:"+acct.getBalance());
		acct.deposit(3000);
		System.out.println("您的账户余额为:"+ acct.getBalance());
	}
}
//=================================================================================================
package 继承和super课后练习;
/*
 * 创建一个Account类的子类CheckAccount代表可透支的账户,
 * 该账户中定义一个属性overdraft代表可透支限额
 * 在CheckAccount类中重写withdraw方法,其算法如下:
 *        如果(取款金额<账户余额)
 *        可直接取款
 *        如果(取款金额>账户余额)
 *        计算需要透支的额度
 *        判断可透支额overdraft是否足够支付本次透支需要,如果可以
 *           将账户余额修改为0,
 */
public class CheckAccount extends Account {
	private double overdraft;//可透支限额
	
	public CheckAccount(int id, double balance, double annualInterestRate,double overdraft) {
		super(id, balance, annualInterestRate);
		this.overdraft=overdraft;
	}
	
	public double getOverdraft() {
		return overdraft;
	}

	public void setOverdraft(double overdraft) {
		this.overdraft = overdraft;
	}

	public void withdraw(double amount) {//余额足够消费
		if(getBalance()>=amount) { 
			//方式一
			//setBalance(getBalance()-amount);
			//方式二
			super.withdraw(amount);
		}else if (overdraft >= amount-getBalance()) //透支额度+余额足够消费
		{
			overdraft -= amount;
		    //setBalance(0); 或
		    super.withdraw(getBalance());
		}else {
			System.out.println("超过可透支限额!");
		}
			
		
	}
}
//==================================================================================================
package 继承和super课后练习;
/*
 * 写一个用户程序测试Account类,在用户程序中,
 * 创建一个账号为1122、余额为20000、年利率为4.5%,可透支限额为5000元的CheckAccount对象
 * 使用withdraw方法提款5000元,并打印账户余额和可透支额
 * 再使用withdraw方法提款18000元,并打印账户余额和可透支额
 * 使用withdraw方法提款3000元,然后打印余额和可透支额
 */
public class CheckAccountTest {
	public static void main(String[] args) {
		CheckAccount acct =new CheckAccount(1122, 20000, 0.045, 5000);
		acct.withdraw(5000);
		System.out.println("您的账户余额为:" + acct.getBalance());
		System.out.println("您的可透支额度为:"+ acct.getOverdraft());
		acct.withdraw(18000);
		System.out.println("您的账户余额为:" + acct.getBalance());
		System.out.println("您的可透支额度为:"+ acct.getOverdraft());
		acct.withdraw(3000);
		System.out.println("您的账户余额为:" + acct.getBalance());
		System.out.println("您的可透支额度为:"+ acct.getOverdraft());
		
}
}

 19.面向对象之多态性

package 多态性的使用;
/*
 * 面向对象特征之三多态性
 * 1.理解多态性:可以理解为一个事物的多种形态
 * 2.何为多态性:对象的多态性,父类的引用指向子类的对象
 * 3.多态的使用,虚拟方法的调用
 *    有了对象的多态性以后,我们在编译期,只能调用父类中声明的方法,但在运行期,我们实际执行的是子类重写父类的方法
 *    总结:编译,看左边;运行,看右边
 * 4.多态性使用前提:①类的继承关系 ②方法的重写
 * 5.对象的多态性只适用于方法不适用于属性
 */
public class PersonTest {
	public static void main(String[] args) {
		Person p1=new Person();
	    p1.eat();
	    
	    Man man=new Man();
	    man.eat();
	    man.age=25;
	    man.earnMoney();
//===============================================
	    System.out.println("******************************");
	    //对象的多态性,父类的引用指向子类的对象
	    Person p2 =new Man();
	    //多态的使用,当调用子父类同名同参数的方法时,实际执行的是子类重写父类的方法---虚拟方法调用
	    p2.eat();//调出来的是子类Man重写的方法
	    p2.walk();
	    
	  //  Person p3 =new Woman();
	}
}
//=================================================================================================
package 多态性的使用举例;
//多态性的使用举例一
public class AnimalTest {
	public static void main(String[] args) {
		AnimalTest test=new AnimalTest();
		test.func(new Dog());
		test.func(new Cat());
	}
	public void func(Animal animal) {//声明的是animal实际上,Animal animal=new Dog();
		animal.eat();
		animal.shout();
	}
	//有了多态性之后,省去了很多重载方法的设计
//	public void func(Dog dog) {
//		dog.eat();
//		dog.shout();
//	}
//	public void func(Cat cat) {
//		cat.eat();
//		cat.shout();
//	}
}
class Animal{
	public void eat() {
		System.out.println("动物进食");
	}
	public void shout() {
		System.out.println("动物叫");
	}
}
class Dog extends Animal{
	public void eat() {
		System.out.println("狗吃骨头");
	}
	public void shout() {
		System.out.println("汪汪汪");
	}
}
class Cat extends Animal{
	public void eat() {
		System.out.println("猫吃鱼");
	}
	public void shout() {
		System.out.println("喵喵喵");
	}
}
//举例二
class Order{
	public void method(Object obj) {
		
	}
}

 向下转型

package 向下转型的使用
/*
 * 面向对象特征之三多态性
 * 1.理解多态性:可以理解为一个事物的多种形态
 * 2.何为多态性:对象的多态性,父类的引用指向子类的对象
 * 3.多态的使用,虚拟方法的调用
 *    有了对象的多态性以后,我们在编译期,只能调用父类中声明的方法,但在运行期,我们实际执行的是子类重写父类的方法
 *    总结:编译,看左边;运行,看右边
 * 4.多态性使用前提:①类的继承关系 ②方法的重写
 * 5.对象的多态性只适用于方法不适用于属性
 ***********************************************************************************
 */
public class PersonTest {
	public static void main(String[] args) {
		Person p1=new Person();
	    p1.eat();
	    
	    Man man=new Man();
	    man.eat();
	    man.age=25;
	    man.earnMoney();
//=====================================================================================
	    System.out.println("******************************");
	    //对象的多态性,父类的引用指向子类的对象
	    Person p2 =new Man();
	    //多态的使用,当调用子父类同名同参数的方法时,实际执行的是子类重写父类的方法---虚拟方法调用
	    p2.eat();//调出来的是子类Man重写的方法
	    p2.walk();
	    
	  //  Person p3 =new Woman();
System.out.println("*****************************************************************");
      //不能调用子类所特有的方法、属性,编译时,p2是person的类型
      p2.nameString="Tom";
//      p2.earMonry():
//      p2.isSmoking = true;
      //有了对象的多态性以后,内存中实际上是加载了子类特有的属性和方法,但是由于变量声明为父类类型,
      //导致编译时,只能调用父类中声明的属性和方法,子类特有的属性和方法不能被调用
      
      //如何才能调用子类特有的属性和方法?使用强制类型转换符
      Man m1 = (Man)p2;//向下转型
      m1.isSmoking = true;
      m1.earnMoney();
      
      //使用强转时,可能出现ClassCastException的异常
//      Woman w1=(Woman)p2;
//      w1.goShopping();
      
      //instanceof关键字的使用
      /*
       * a instanceof A:判断对象a是否是类A的实例,如果是,返回true如果不是返回false
       * 使用情境:为了避免在向下转型时出现ClassCastException的异常,所以我们在向下转型之前
       * 先进行instanceof的判断,一旦返回true就向下转型,如果返回false,不进行向下转型
       * 
       * 如果a instanceof A返回true,则a instanceof B也返回true
       * 其中,类B是类A的父类
       */
      if(p2 instanceof Woman) {
    	  Woman w1=(Woman)p2;
    	  w1.goShopping();
    	  System.out.println("*******Woman*******");
      }
      if(p2 instanceof Woman) {
    	  Man m2=(Man)p2;
    	  m2.earnMoney();
    	  System.out.println("*******Woman*******");
      }
      
      //练习“
      //问题一:编译通过,运行时不通过
//举例一     Person p3 = new Woman();
//           Man m3 = (Man)p3;                  出现这种情况 加instanceof
//举例二     Person p4 = new Person();
//           Man m4=(Man)p4;
      //问题二:编译通过,运行时也通过
      Object obj = new Woman();
      Person person = (Person)obj;
	}
}

 关键字:static

1.1、static 的使用
当我们编写一个类时,其实就是在描述其对象的属性和行为,而并没有产生实质上的对象,只有通过 new 关键字才会产生出对象,这时系统才会分配内存空间给对象,其方法才可以供外部调用。

我们有时候希望无论是否产生了对象或无论产生了多少对象的情况下,某些特定的数据在内存空间里

/*
 * static 关键字的使用
 * 
 * 1.static:静态的。
 * 2.static 可以用来修饰:属性、方法、代码块、内部类。
 * 
 * 3.使用 static 修饰属性:静态变量(或类变量)。
 * 		3.1  属性:是否使用 static 修饰,又分为:静态属性 VS 非静态属性(实例变量)
 * 		   实例变量:我们创建了类的多个对象,每个对象都独立的拥有了一套类中的非静态属性。
 * 				当修改其中一个非静态属性时,不会导致其他对象中同样的属性值的修饰。
 * 		   静态变量:我们创建了类的多个对象,多个对象共享同一个静态变量。当通过静态变量去修改某一个变量时,
 * 				会导致其他对象调用此静态变量时,是修改过的。
 * 		3.2 static 修饰属性的其他说明:
 * 			① 静态变量随着类的加载而加载。可以通过"类.静态变量"的方式进行调用。
 * 			② 静态变量的加载要早于对象的创建。
 * 			③ 由于类只会加载一次,则静态变量在内存中也只会存在一次。存在方法区的静态域中。
 * 
 * 			④ 		类变量		实例变量
 * 			类		yes			no
 * 			对象		yes			yes
 * 
 * 		3.3 静态属性举例:System.out.Math.PI;
 *  
 */
public class StaticTest {
	public static void main(String[] args) {
		
		Chinese.nation = "中国";
		
		Chinese c1 = new Chinese();
		c1.name = "姚明";
		c1.age = 40;
		c1.nation = "CHN";
		
		Chinese c2 = new Chinese();
		c2.name = "马龙";
		c2.age = 30;
		c2.nation = "CHINA";
		
		System.out.println(c1.nation); 
		
		//编译不通过
//		Chinese.name = "张继科";
		
	}
}
//中国人
class Chinese{
	
	String name;
	int age;
	static String nation;
}

 

/* 
 * 4.使用 static 修饰方法:静态方法
 * 		① 随着类的加载而加载,可以通过"类.静态方法"的方式调用
 * 		② 			静态方法		非静态方法
 * 			类		yes			no
 * 			对象		yes			yes
 * 		③ 静态方法中,只能调用静态的方法或属性
 * 		  非静态的方法中,可以调用所有的方法或属性
 * 
 * 5.static 注意点:
 * 	 5.1  在静态的方法内,不能使用 this 关键字、super 关键字
 *   5.2 关于静态属性和静态方法的使用,大家从生命周期的角度去理解。
 *   
 * 6.开发中,如何确定一个属性是否需要声明 static 的?
 * 	 》 属性是可以被多个对象所共享的,不会随着对象的不同而不同的。
 * 	 》 类中的常量也常常声明为 static
 *   
 *   开发中,如何确定一个方法是否要声明为 static 的?
 *   》 操作静态属性的方法,通常设置为 static 的
 *   》 工具类中的方法,习惯上声明为 static 的。比如:Math、Arrays、Collections
 * 	 
 */
public class StaticTest {
	public static void main(String[] args) {
		
		Chinese.nation = "中国";
		
		Chinese c1 = new Chinese();
		
		//编译不通过
//		Chinese.name = "张继科";
		
		c1.eat();
		
		Chinese.show();
		//编译不通过
//		chinese.eat();
//		Chinese.info();
	}
}
//中国人
class Chinese{
	
	String name;
	int age;
	static String nation;
	
	public void eat(){
		System.out.println("中国人吃中餐");
		//调用非静态结构
		this.info();
		System.out.println("name : " + name);
		//调用静态结构
		walk();
		System.out.println("nation : " + Chinese.nation);
	}
	
	public static void show(){
		System.out.println("我是一个中国人!");
//		eat();
//		name = "Tom";
		//可以调用静态的结构
		System.out.println(Chinese.nation);
		walk();
	}
	
	public void info(){
		System.out.println("name : " + name + ",age : " + age);
	}
	
	public static void walk(){
		
	}
}

 自定义ArrayUtil

/*
 * 自定义数组工具类
 */
public class ArrayUtil {

	// 求数组的最大值
	public static int getMax(int[] arr) {
		int maxValue = arr[0];
		for (int i = 1; i < arr.length; i++) {
			if (maxValue < arr[i]) {
				maxValue = arr[i];
			}
		}
		return maxValue;
	}

	// 求数组的最小值
	public static int getMin(int[] arr) {
		int minValue = arr[0];
		for (int i = 1; i < arr.length; i++) {
			if (minValue > arr[i]) {
				minValue = arr[i];
			}
		}
		return minValue;
	}

	// 求数组总和
	public static int getSum(int[] arr) {
		int sum = 0;
		for (int i = 0; i < arr.length; i++) {
			sum += arr[i];
		}
		return sum;
	}

	// 求数组平均值
	public static int getAvg(int[] arr) {
		int avgValue = getSum(arr) / arr.length;
		return avgValue;
	}

	//如下两个同名方法构成重载
	// 反转数组
	public static void reverse(int[] arr) {
		for (int i = 0; i < arr.length / 2; i++) {
			int temp = arr[i];
			arr[i] = arr[arr.length - i - 1];
			arr[arr.length - i - 1] = temp;
		}
	}
	
	public void reverse(String[] arr){
		
	}

	// 复制数组
	public static int[] copy(int[] arr) {
		int[] arr1 = new int[arr.length];
		for (int i = 0; i < arr1.length; i++) {
			arr1[i] = arr[i];
		}
		return null;
	}

	// 数组排序
	public static void sort(int[] arr) {
		for (int i = 0; i < arr.length - 1; i++) {
			for (int j = 0; j < arr.length - 1 - i; j++) {
				if (arr[j] > arr[j + 1]) {
//					int temp = arr[j];
//					arr[j] = arr[j + 1];
//					arr[j + 1] = temp;
					//错误的:
//					swap(arr[j],arr[j+1]);
					
					swap(arr,j ,j+1);
				}
			}
		}
	}
	
	//错误的:交换数组中两个指定位置元素的值
//	public void swap(int i,int j){
//		int temp = i;
//		i = j;
//		j = temp;
//	}
	
	//正确的:
	private static void swap(int[] arr,int i,int j){
		int temp = arr[i];
		arr[i] = arr[j];
		arr[j] = temp;
	}

	// 遍历数组
	public static void print(int[] arr) {
		System.out.print("[");
		for (int i = 0; i < arr.length; i++) {
			System.out.print(arr[i] + ",");
		}
		System.out.println("]");
	}

	// 查找指定元素
	public static int getIndex(int[] arr, int dest) {
		//线性查找
		for (int i = 0; i < arr.length; i++) {

			if (dest==arr[i]) {
				return i;
			}

		}
		return -1;
	}

}

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值