JAVA笔记(面向对象)

Java面向对象与面向过程

     面向过程(Procedure Oriented)和面向对象(Object Oriented,OO)都是对软件分析、设计和开发的一种思想,它指导着人们以不同的方式去分析、设计和开发软件。早期先有面向过程思想,随着软件规模的扩大,问题复杂性的提高,面向过程的弊端越来越明显的显示出来,出现了面向对象思想并成为目前主流的方式。两者都贯穿于软件分析、设计和开发各个阶段,对应面向对象就分别称为面向对象分析(OOA)、面向对象设计(OOD)和面向对象编程(OOP)。C语言是一种典型的面向过程语言,Java是一种典型的面向对象语言。

         相同点:两者都是解决问题的思维方式,代码组织的方式。
         区别:从特征上面向对象有三个特征即:封装性、继承性、多态性。而面向过程没有继承性、多态性,解决问题上:

         宏观上使用面向对象,微观上使用面向过程,面向过程适合简单、不需要协作的事务。

         联系:面对对象包括面对过程,两者相辅相成。

Java继承

     继承是java面向对象编程技术的一块基石,因为它允许创建分等级层次的类。继承可以理解为一个对象从另一个对象获取属性的过程。在JAVA中,类的继承是单一的,即一个子类只拥有一个父类。列如:如果类A是类B的父类,而类B是类C的父类,我们也称C是A的子类,类C是从类A继承而来的。

       继承关键字:extends   implements

       通过使用关键字extends,子类可以继承父类的除private属性外所有的属性。

       通过使用关键字implements,在类在继承接口的情况下使用

package java05;
/**
 * 继承
 * @author Administrator
 *
 */
public class JavaInherit {

	public static void main(String[] args) {
		Student stu1=new Student("java", "张三", 168);
		stu1.rest();
		stu1.study();
		//instanceof 二元运算符,左边对象右边类
		System.out.println(stu1 instanceof Person);
		System.out.println(stu1 instanceof Student);


	}
}
//父类  Personn类
class Person{
		String name;
		int height;
		public void rest() {
			System.out.println("休息一会!!");
		}
	}
//继承关键字extends 子类Student类
class Student extends Person{
	   String major;
	   public void study() {
		   System.out.println("我在蓝云学习java");
	   }
	public Student(String major,String name,int height) {
		super();
		this.major = major;
		this.height=height;
		this.name=name;
		
	}
	  
	
   }

      注:

         1.父类也称作超类、基类、派生类等。

         2.Java中过于复杂,系统难于维护。

         3.Java中类没有多继承,接口有多继承。 只有单继承,没有像C++那样的多继承。多继承会引起混乱,使得继承链

         4.子类继承父类,可以得到父类的全部属性和方法 (除了父类的构造方法),但不见得可以直接访问(比如,父类私有的属性和方法)。

          5.如果定义一个类时,没有调用extends,则它的父类是:java.lang.Object。 

Java 重写(Override)与重载(Overload)

          重写(Override):重写是子类对父类的允许访问的方法的实现过程进行重新编写!返回值和形参都不能改变。即外壳不变,核心重写!重写的好处在于子类可以根据需要,定义特定于自己的行为。也就是说子类能够根据需要实现父类的方法。在面向对象原则里,重写意味着可以重写任何现有方法

  

package java05;
/**
 * 方法重写
 * @author Administrator
 *
 */

public class JavaMethodOverride {
	public static void main(String[] args) {
		Vehicle v1=new Vehicle();
		Vehicle v2=new Horse();
		Vehicle v3=new Plane();
		v1.run();
		v2.run();
		v3.run();
		v1.stop();
		v3.stop();
		
	}	
}


//父类
class Vehicle{
	//run方法
	public void run() {
		System.out.println("跑");
	}
	//stop方法
	public void stop() {
		System.out.println("停止不动");
	}
}
//子类1
class Horse extends Vehicle{
	//重写方法run
	public void run() {
		System.out.println("跑等飞快");
	}
}
//子类二
class Plane extends Vehicle{
	public void run() {
		System.out.println("天上飞!!!");
	}
	public void stop() {
		System.out.println("坠机了!!!!!");
	}
}

方法重写的规则
 *  参数列表必须完全与被重写方法的相同; 返回类型必须完全与被重写方法的返回类型相同;
 * 子类方法的访问权限必须大于或等于父类方法的访问权限。例如:如果父类的一个方法被声明为public,那么在子类中重写该方法就不能声明为protected。
 * 父类的成员方法只能被它的子类重写。 声明为final的方法不能被重写。 声明为static的方法不能被重写,但是能够被再次声明。
 * 子类和父类在同一个包中,那么子类可以重写父类所有方法,除了声明为private和final的方法。
 * 子类和父类不在同一个包中,那么子类只能够重写父类的声明为public和protected的非final方法。
 * 重写的方法能够抛出任何非强制异常,无论被重写的方法是否抛出异常。但是,重写的方法不能抛出新的强制性异常,或者比被重写方法声明的更广泛的强制性异常,
 * 反之则可以。 构造方法不能被重写。 如果不能继承一个方法,则不能重写这个方法。

重载(Overload):重载(overloading) 是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同。每个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表。只能重载构造函数

package javabiji;
/**
 * 重载
 */

import org.omg.CORBA.PUBLIC_MEMBER;

public class JavaOverLoad {
	public static void main(String[] args) {
		//已见过的方法重载
		System.out.println();
		System.out.println(1);
		System.out.println(3.5);
		
		
			
	}
	/*求和方法*/
	public static int add(int n1,int n2) {
		int sum=n1+n2;
		return sum;
	}
	
	/*方法名相同,参数列表不同, 构成重载*/
	public static int add(int n1,int n2,int n3) {
		int sum=n1+n2+n3;
		return sum;
    }
	/*方法名相同,参数类型不同,构成重载*/
	public static double add(double n1,int n2) {
		double sum=n1+n2;
		return sum;
	}
	
	/*编译错误,只有返回值不同,不构成重载*/
//	public static double add(int n1,int n2) {
//		double sum=n1+n2;
//		return sum;
//	}
	
	/*编译错误,只有参数名称不同,不构成重载*/
//	public static double add(int n2,int n1) {
//		double sum=n1+n2;
//		return sum;
//	}
}

 

  重载规则

     *被重载的方法必须改变参数列表;

     *被重载的方法可以改变返回类型;

     *被重载的方法可以改变访问修饰符;

     *被重载的方法可以声明新的或更广的检查异常;

     *方法能够在同一个类中或者在一个子类中被重载。

Java多态

     

    多态指的是同一个方法调用,由于对象不同可能会有不同的行为。现实生活中,同一个方法,具体实现会完全不同。比如:同样是调用人的“休息”方法,张三是睡觉,李四是旅游,赵程序员是敲代码

多态的优点

    1. 消除类型之间的耦合关系

    2. 可替换性

   3. 可扩充性

   4. 接口性

   5. 灵活性

   6. 简化性

多态存在的三个必要条件

1、继承

2、重写

3、父类引用指向子类对象

当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,再去调用子类的同名方法。

多态的好处:可以使程序有良好的扩展,并可以对所有类的对象进行通用处理。

package javabiji;
/**
 *面向对象的多态
 * @author Administrator
 *
 */
public class JavaPolym {

	public static void main(String[] args) {
		Animal a1=new Cat();//向上可以自动转型
		//传的是哪一个类型就调用哪一个方法,大大提高了程序的可扩展类型
		animalCry(a1);
		
		Animal a2=new Dog();
		
		animalCry(a2);//a2为编译类型,Dog对象才是运行过时类型
		
		//片写程序时,如果想调用运行时类型的方法,只能进行强制性类型转换,否则编译报错
//		Dog dog =(Dog)a2;
//		dog.seeDoor();
		
		//向下转型
//		Animal c=new Cat();
//		Dog d3=(Dog)c;
//		d3.seeDoor();
	}
	
	
	//有了多态,只需要让增加的这个类继承Animal类就可以了
	static void animalCry(Animal a) {
		a.shout();
	}
	
	
	/*
	 * //如果没有多态就需要写很多的方法重载,每增加同一种动物就需要重载一种动物的shout方法
	 *  static void animalCry(Dog d) {
	 *         d.shout(); 
	 *   }
	 *  static void animalCry(Cat c) { 
	 *        c.shout();
	 *  }
	 */}
class Animal{
	public void shout() {
		System.out.println("动物叫声!");
	}
}
class Cat extends Animal{
	public void shout() {
		System.out.println("汪  汪 汪!");
	}
	

}
class Dog extends Animal{
	public void shout() {
		System.out.println("喵喵喵!");
	}
	public void seeDoor() {
		System.out.println("看门中");
	}

}

输出结果:

汪  汪 汪!
喵喵喵!

Java封装

在面向对象程式设计方法中,封装(英语:Encapsulation)是指,一种将抽象性函式接口的实作细节部份包装、隐藏起来的方法。

封装可以被认为是一个保护屏障,防止该类的代码和数据被外部类定义的代码随机访问。

要访问该类的代码和数据,必须通过严格的接口控制。

封装最主要的功能在于我们能修改自己的实现代码,而不用修改那些调用我们代码的程序片段。

适当的封装可以让程式码更容易理解与维护,也加强了程式码的安全性。

封装的优点

1. 良好的封装能够减少耦合。

2. 类内部的结构可以自由修改。

3. 可以对成员变量进行更精确的控制。

4. 隐藏信息,实现细节。

实现Java封装的步骤

1. 修改属性的可见性来限制对属性的访问(一般限制为private),例如:

public class Person {
    private String name; 
    private int age;

}

这段代码中,将 name 和 age 属性设置为私有的,只能本类才能访问,其他类都访问不了,如此就对信息进行了隐藏。

2. 对每个值属性提供对外的公共方法访问,也就是创建一对赋取值方法,用于对私有属性的访问,例如:

public class Person{  
  private String name;   
  private int age;  
  public int getAge(){  
    return age;  
  }  
 public String getName(){ 
     return name;   
 }
  public void setAge(int age){   
   this.age = age;    
  }
   public void setName(String name){  
    this.name = name;   
   }
}

采用 this 关键字是为了解决实例变量(private String name)和局部变量(setName(String name)中的name变量)之间发生的同名的冲突。

以上实例中public方法是外部类访问该类成员变量的入口。

通常情况下,这些方法被称为getter和setter方法。

因此,任何要访问类中私有成员变量的类都要通过这些getter和setter方法。   注意!!! boolean类型的get()方法开头是is!!!

通过如下的例子说明EncapTest类的变量怎样被访问:

/* F文件名 : RunEncap.java */
public class RunEncap{  
 public static void main(String args[]){      
   EncapTest encap = new EncapTest();    
   encap.setName("James");   
   encap.setAge(20);     
   encap.setIdNum("12343ms");     
   System.out.print("Name : " + encap.getName()+ " Age : "+ encap.getAge());  
  }
}

Java接口

接口(英文:Interface),在JAVA编程语言中是一个抽象类型,是抽象方法的集合,接口通常以interface来声明。一个类通过继承接口的方式,从而来继承接口的抽象方法。

接口并不是类,编写接口的方式和类很相似,但是它们属于不同的概念。类描述对象的属性和方法。接口则包含类要实现的方法。

除非实现接口的类是抽象类,否则该类要定义接口中的所有方法。

接口无法被实例化,但是可以被实现。一个实现接口的类,必须实现接口内所描述的所有方法,否则就必须声明为抽象类。另外,在Java中,接口类型可用来声明一个变量,他们可以成为一个空指针,或是被绑定在一个以此接口实现的对象。

接口与类相似点:

  • 一个接口可以有多个方法。
  • 接口文件保存在.java结尾的文件中,文件名使用接口名。
  • 接口的字节码文件保存在.class结尾的文件中。
  • 接口相应的字节码文件必须在与包名称相匹配的目录结构中。

接口与类的区别:

  • 接口不能用于实例化对象。
  • 接口没有构造方法。
  • 接口中所有的方法必须是抽象方法。
  • 接口不能包含成员变量,除了static和final变量。
  • 接口不是被类继承了,而是要被类实现。
  • 接口支持多重继承。

 


接口的声明

接口的声明语法格式如下:

[可见度] interface 接口名称 [extends 其他的类名] {
        // 声明变量
        // 抽象方法
}

Interface关键字用来声明一个接口。下面是接口声明的一个简单例子。

/* 文件名 : NameOfInterface.java */
import java.lang.*;
//引入包

public interface NameOfInterface
{
   //任何类型 final, static 字段
   //抽象方法
}

接口有以下特性:

 1. 访问修饰符:只能是public或默认。

 2. 接口名:和类名采用相同命名机制。

 3. extends:接口可以多继承。

 4. 常量:接口中的属性只能是常量,总是:public static final 修饰。不写也是。

 5. 方法:接口中的方法只能是:public abstract。 省略的话,也是public abstract。

实例

/* 文件名 : Animal.java */
interface Animal {

   public void eat();
   public void travel();
}

接口的实现

当类实现接口的时候,类要实现接口中所有的方法。否则,类必须声明为抽象的类。

类使用implements关键字实现接口。在类声明中,Implements关键字放在class声明后面。

实现一个接口的语法,可以使用这个公式:

... implements 接口名称[, 其他接口, 其他接口..., ...] ...

实例

/* 文件名 : MammalInt.java */
public class MammalInt implements Animal{

   public void eat(){
      System.out.println("Mammal eats");
   }

   public void travel(){
      System.out.println("Mammal travels");
   } 

   public int noOfLegs(){
      return 0;
   }

   public static void main(String args[]){
      MammalInt m = new MammalInt();
      m.eat();
      m.travel();
   }
} 

以上实例编译运行结果如下:

Mammal eats
Mammal travels

重写接口中声明的方法时,需要注意以下规则:

  • 类在实现接口的方法时,不能抛出强制性异常,只能在接口中,或者继承接口的抽象类中抛出该强制性异常。
  • 类在重写方法时要保持一致的方法名,并且应该保持相同或者相兼容的返回值类型。
  • 如果实现接口的类是抽象类,那么就没必要实现该接口的方法。

在实现接口的时候,也要注意一些规则:

  • 一个类可以同时实现多个接口。
  • 一个类只能继承一个类,但是能实现多个接口。
  • 一个接口能继承另一个接口,这和类之间的继承比较相似。

接口的继承

一个接口能继承另一个接口,和类之间的继承方式比较相似。接口的继承使用extends关键字,子接口继承父接口的方法。

下面的Sports接口被Hockey和Football接口继承:

 

// 文件名: Sports.java
public interface Sports
{
   public void setHomeTeam(String name);
   public void setVisitingTeam(String name);
}

// 文件名: Football.java
public interface Football extends Sports
{
   public void homeTeamScored(int points);
   public void visitingTeamScored(int points);
   public void endOfQuarter(int quarter);
}

// 文件名: Hockey.java
public interface Hockey extends Sports
{
   public void homeGoalScored();
   public void visitingGoalScored();
   public void endOfPeriod(int period);
   public void overtimePeriod(int ot);
}

 

Hockey接口自己声明了四个方法,从Sports接口继承了两个方法,这样,实现Hockey接口的类需要实现六个方法。

相似的,实现Football接口的类需要实现五个方法,其中两个来自于Sports接口。


接口的多重继承

在Java中,类的多重继承是不合法,但接口允许多重继承,。

在接口的多重继承中extends关键字只需要使用一次,在其后跟着继承接口。 如下所示:

public interface Hockey extends Sports, Event

以上的程序片段是合法定义的子接口,与类不同的是,接口允许多重继承,而 Sports及 Event 可能定义或是继承相同的方法


没有任何方法的接口被称为标记接口。标记接口主要用于以下两种目的:

建立一个公共的父接口

正如EventListener接口,这是由几十个其他接口扩展的Java API,你可以使用一个标记接口来建立一组接口的父接口。例如:当一个接口继承了EventListener接口,Java虚拟机(JVM)就知道该接口将要被用于一个事件的代理方案。

向一个类添加数据类型:

这种情况是标记接口最初的目的,实现标记接口的类不需要定义任何接口方法(因为标记接口根本就没有方法),但是该类通过多态性变成一个接口类型。

Java包(package)

为了更好地组织类,Java提供了包机制,用于区别类名的命名空间。

包的作用

  • 1 把功能相似或相关的类或接口组织在同一个包中,方便类的查找和使用。
  • 2 如同文件夹一样,包也采用了树形目录的存储方式。同一个包中的类名字是不同的,不同的包中的类的名字是可以相同的,当同时调用两个不同包中相同类名的类时,应该加上包名加以区别。因此,包可以避免名字冲突。
  • 3 包也限定了访问权限,拥有包访问权限的类才能访问某个包中的类。

Java使用包(package)这种机制是为了防止命名冲突,访问控制,提供搜索和定位类(class)、接口、枚举(enumerations)和注释(annotation)等。

包语句的语法格式为:

package pkg1[.pkg2[.pkg3…]];

例如,一个Something.java 文件它的内容

package net.java.util
public class Something{
   ...
}

那么它的路径应该是 net/java/util/Something.java 这样保存的。 package(包)的作用是把不同的java程序分类保存,更方便的被其他java程序调用。

一个包(package)可以定义为一组相互联系的类型(类、接口、枚举和注释),为这些类型提供访问保护和命名空间管理的功能。

以下是一些Java中的包:

  • java.lang-打包基础的类
  • java.io-包含输入输出功能的函数

开发者可以自己把一组类和接口等打包,并定义自己的package。而且在实际开发中这样做是值得提倡的,当你自己完成类的实现之后,将相关的类分组,可以让其他的编程者更容易地确定哪些类、接口、枚举和注释等是相关的。

由于package创建了新的命名空间(namespace),所以不会跟其他package中的任何名字产生命名冲突。使用包这种机制,更容易实现访问控制,并且让定位相关类更加简单。


创建包

创建package的时候,你需要为这个package取一个合适的名字。之后,如果其他的一个源文件包含了这个包提供的类、接口、枚举或者注释类型的时候,都必须将这个package的声明放在这个源文件的开头。

包声明应该在源文件的第一行,每个源文件只能有一个包声明,这个文件中的每个类型都应用于它。

如果一个源文件中没有使用包声明,那么其中的类,函数,枚举,注释等将被放在一个无名的包(unnamed package)中。

例子

让我们来看一个例子,这个例子创建了一个叫做animals的包。通常使用小写的字母来命名避免与类、接口名字的冲突。

在animals包中加入一个接口(interface):

/* 文件名: Animal.java */
package animals;

interface Animal {
   public void eat();
   public void travel();
}

接下来,在同一个包中加入该接口的实现:

package animals;

/* 文件名 : MammalInt.java */
public class MammalInt implements Animal{

   public void eat(){
      System.out.println("Mammal eats");
   }

   public void travel(){
      System.out.println("Mammal travels");
   } 

   public int noOfLegs(){
      return 0;
   }

   public static void main(String args[]){
      MammalInt m = new MammalInt();
      m.eat();
      m.travel();
   }
} 

然后,编译这两个文件,并把他们放在一个叫做animals的子目录中。 用下面的命令来运行:


import关键字

为了能够使用某一个包的成员,我们需要在 Java 程序中明确导入该包。使用"import"语句可完成此功能。

在 java 源文件中 import 语句应位于 package 语句之后,所有类的定义之前,可以没有,也可以有多条,其语法格式为:

package javabiji;
//导包方法一
import java.util.Date;
//import java.util.Scanner;
import java.util.*;//导包方法二 导入该包下的所有包,会降低编译速度,但是不会降低运行速度

public class JavaPackage {

	public static void main(String[] args) {
		//这里指的是java.sql.Date
		Date now;
		//java.sql.Date因为和ava.util.Date类同名,需要完整路径
		java.util.Date  now2=new java .util.Date();
		System.out.println(now2);
		//java.util包的非同名类不需要完整路径
		Scanner input=new Scanner(System.in);

	}

}

如果在一个包中,一个类想要使用本包中的另一个类,那么该包名可以省略。

  

 

 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值