类、对象、接口

本文为 Week4 笔记
Java程序设计 唐大仕

  • 组成Java程序的基本要素
  • 是一类对象的原型
  • 封装类一类对象的状态和方法

字段和方法

  • 字段(field)是类的属性,是用变量来表示的。字段又称为域、属性、成员变量
  • 方法(method)是类的功能和操作,是用函数来表示的

构造方法

  • 构造方法是一种特殊的方法
  • 用来初始化(new)该类的一个新的对象
  • 构造方法和类名同名,而且不写返回值类型

默认构造方法

  • 一般情况下,类都有一个至多个构造方法
  • 如果没有定义任何构造方法,系统会自动产生一个构造方法,称为默认构造方法(default constructor)
  • 默认构造方法不带参数,并且方法体为空

方法重载(overload)

  • 方法的重载(overloading):多个方法有相同的名字,编译 时能识别出来
  • 这些方法的 签名 不同(signature),或者是参数个数不同,或者是参数类型不同
  • 通过方法的重载可以实现多态(polymorphism)
  • 重载的作用 是允许方法的使用者采用不同的参数来调用相同名称的方法
  • 方法类型签名 包括方法名称和参数类型两个部分
class MethodOverloadingTest
	{
	public static void main( String[] argv ){
		Person p1 = new Person("Tom", 20);
		Person p2 = new Person("Marry", 18);
		p1.sayHello();
		p1.sayHello(p2);
	}
	}
	class Person
	{
	String name;
	int age;
	Person( String name, int age ){
		this.name = name;
		this.age = age;
	}

	void sayHello(){
		System.out.println("Hello! My name is " + name );
	}

	void sayHello( Person another ){
		System.out.println("Hello, " + another.name + "! My name is " + name );
	}

	}

this的使用

  • 在方法及构造方法中,使用this来访问字段及方法
  • 是用this解决局部变量与域变量同名的问题,局部变量(方法中的变量)或参数变量与域名变量同名的问题。
Person( int age, String name )
	{
		this.age = age;
		this.name = name;
	}

	this.age表示域变量,而age表示的是参数变量
  • 在构造方法中,用this调用里一个构造方法,在构造函数中调用另一个构造方法,则这条语句必须放在第一句
  class Person {
	String name;
	int age;
	Person( String n, int a ){
		name = n;
		age = a;
	}
	Person( String n ){
		name = n;
		age = 0;
	}
	Person( int age, String name )
	{
		this.age = age;
		this.name = name;
	}
	Person(  ){
		this( 0, "" );
	}
	boolean isOlderThan( int anAge ){
		return this.age > anAge;
	}
	void sayHello(){
		System.out.println("Hello! My name is " + name );
	}
	void sayHello( Person another ){
		System.out.println("Hello," + another.name 
			+ "! My name is " + name );
	}
	public static void main(String[] args) 
	{
		Person p = new Person("Li Min", 18);
		Person p2 = new Person("Wang Qiang", 20 );
		p.sayHello();
		p.sayHello(p2);
	}
	}

继承

  • 继承是面型对象程序设计中最重要的特征之一
  • 子类(subclass)父类或超类(superclass)
  • 父类包括所有直接或间接被继承的类
  • Java支持单继承:一个类只能有一个直接父类

继承的好处

子类继承父类的状态和行为

  • 可以修改父类的状态或重载父类的行为
  • 可以添加新的状态和行为
  • 所有的类都是直接或间接继承java.lang.Objectd得到的

好处

  • 可以提高程序的抽象程度
  • 实现代码重用,提高开发效率和可维护性

字段

  • 字段的继承:子类可以继承父类的所有字段
  • 字段的隐藏:子类重新定义一个与从父类那里继承来的与变量完全相同的变量,称为域的隐藏
  • 字段的添加:在定义子类的时,加上新的域变量,就可以使子类比父类多一些属性

方法

  • 方法的继承:父类的非私有方法可以被子类自动继承

  • 方法的覆盖(Override)(修改) 子类也可以重新定义与父类同名的方法,实现对父类方法的覆盖(Override)
    JDK 1.5 可以使用Override 来标注

  • 方法的添加:子类可以添加一些新的方法

  • 方法的重载:重载父类的同名方法,重载的方法实际上是新加的方法。

super的使用

  • 构造函数是不能继承的,但是子类可以通过super来调用父类的构造方法
  • 使用super访问父类的域和方法
  • 使用super时 super() 必须放在第一句
 public class RoundImageView extends ImageView {
    private int mBorderThickness = 0;  
    private Context mContext;  
    private int defaultColor = 0xFFFFFFFF;  
    private int mBorderOutsideColor = 0;  
    private int mBorderInsideColor = 0;  
    private int defaultWidth = 0;  
    private int defaultHeight = 0;  
      public RoundImageView(Context context) {
        super(context);  
        mContext = context;  
    }  
    public RoundImageView(Context context, AttributeSet attrs) {
        super(context, attrs);  
        mContext = context;  
        setCustomAttributes(attrs);  
    }  
      public RoundImageView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);  
        mContext = context;  
        setCustomAttributes(attrs);  
    }  

父类对象与子类对象的转换

  • 子类对象可以被视为其父类的一个对象
  • 父类对象不能被当作其某一个子类的对象
  • 如果一个方法的形式参数定义为父类对象,那么在调用这个方法时,可以使用子类对象作为实际参数
  • 如果父类对象引用指向的实际是一个子类对象,那么这个父类对象的引用可以用强制类型转换(casting)成子类对象的引用

  • 包的作用:解决名字空间、名字冲突
  • 包的含义:a.名字空间、存储路径(文件夹)b.可访问性(同一包下的各个类默认是可以相互访问的)
  • 包层次的根目录是由环境变量CLASSPATH来确定的
  • 简单情况下,没有package语句,这时称为无名包(unnamend package)

import语句

  • java编译器自动导入包java.lang.*

  • 注意:使用 * 只能表示本层的所有类,不包括子层下的类

CLASSPATH

  • 包层次的根目录是由环境变量CLASSPATH来确定的。
  • 方法一: 在java 及javac 命令中,用-classpath(或-cp)选项来指明,如: java -classpath d:\code;d:\code\java\classes
  • set classpath= D:\code\Java\learncode\ch04\pk;.

访问控制符

成员的访问控制符

同一个类中 同一个包中 不同包中的子类 不同包中的非子类
priavte Yes
默认访问权限(包访问权限) Yes Yes
protected Yes Yes Yes
public Yes Yes Yes Yes

seter和getter

  • 属性使用private更好的封装和隐藏,外部类不能随意的存取和修改
  • 提供方法来存取对象的属性,在方法中可以对给定的参数的合法性进行校验
  • 方法可以用来给出计算后的值
  • 方法可以完成其他必要的工作(如清理资源、设定状态,等等)
  • 只提供getXX方法,而不提供setXx方法,可以保证属性是只读的

非访问控制符

基本含义 修饰符 修饰成员 修饰的局部变量
static 静态的、非实例的、类的 可以修饰内部类 Yes
默认访问权限(包访问权限) Yes Yes
final 最终的、不可改变的 Yes Yes Yes
abstract 抽象的、不可实例化的 Yes Yes

static 字段

  • 静态字段最本质的特点是:它是类的字段,不属于任何一个对象实例
  • 它不保存在某个对象实例的内存区间中,而是保存在类的内存区域的公共存储单元
  • 类变量可以通过类名直接访问,以可以通过实例对象来访问,两种方法的结果是相同的
  • static在一定意义上,剋来表示全局变量

static 方法

  • 用static修饰符修饰的方法仅属于类的静态方法,又称为类方法
  • 于此相对,不用static修饰的方法,则为实例方法
  • 类方法的本质是该方法是属于整个类,不是属于某个类的实例的
  • 声明一个方法为static有以下几重含义
  • (1)非static的方法是属于某个对象的方法,在这个对象创建时,对象的方法在内存中拥有自己专用的代码段。
    而static方法是属于整个类的,它在内存中的代码段将随着类的定义而进行分配和装载,不被任何一个对象专有
  • (2)由于static方法是属于整个类的,所以它不能操纵和处理属于某个对象的的成员变量,而只能处理整个类的
    成员变量,即static方法只能处理本类中的static域或调用static方法
  • (3)static方法中,不能访问实例变量,不能使用this 或super
  • (4)调用这个方法时,应该使用类名直接调用,也可以用某一个具体的对象名

final类

  • 如果一个类被定义为final修饰和限定,说明这个类不能被继承,即不可能有子类

final方法

  • final修饰符所修饰的方法,而不能被子类所覆盖的方法

final字段及final局部变量

final字段、final局部变量(方法中的变量)

  • 它们的值一旦给定就不能修改
  • 只读的,它们能切只能被赋值一次,而不能被赋值多次

一个字段被 static final 两个修饰符所限定时,它可以表示常量 如:Math.PI

关于赋值

  • 在定义static final 域时,若不给定初始值,则按默认值进行初始化(数值为 0,boolean 为false ,引用类型为null)
  • 在定义final字段时,若不是static的域,则必须只能赋值一次,不能缺省 这种赋值方式有两种:一种是在定义
    变量时赋值初始化,二是子啊每一个构造函数中进行赋值
  • 在定义为final局部变量时,必须且只能赋值一次。他的值可能不是常量,但它的取值在变量存在期间不会改变

abstract

  • 凡是用abstract修饰的类被称为抽象类
  • 抽象类不能实例化

抽象类的意义

为其子类提供一个公共的类型 封装子类中得重复内容 定义抽象方法,子类虽然有不同的实现 但是定义是一致的

abstract方法

  • 被abstract所修饰的方法叫抽象方法抽象方法的作用在所有的子类定义一个统一的接口。对象方法只需要声明,而不需要实现,即用分号(;)而不是用{},格式如下:
  • abtract retutrnType abstracmethod([]);
  • 抽象类可以包含抽象方法,也可以不包含抽象方法。但是,一旦某个类中包含类abstract方法,则这个类必须声明为
    抽象类
  • 抽象方法在子类中必须被实现,否则子类任然是abstract的

接口:某种特征的约定

  • 所有的方法都自动的是 public abstract
  • 接口的实现 implements 可以实现多继承,和类的继承关系无关
  • 通过接口可以实现不相关类的相同行为,而不需考虑这些类之间的层次关系。从而一定意义上实现了多继承
  • 通过接口可以实现多个类需要实现的方法
  • 通过接口可以了解对象的交互界面,而不需要了解对象所对应的类
  • 通常以able或ible结尾,表明接口能完成一定的行为
  • 接口声明中还可以包括对接口的访问权限以及它的父接口列表
[public] interface interfaceName [extends listOfsuperInterface]{
		...
	}
  • 其中public指明任意类可使用这个接口,缺省情况下,只能与该接口点过意在同一个包中的类才可以访问这个接口
  • extends 子句与类声明中的 extends子句基本相同,不同的是一个接口可以有多个父接口,用逗号隔开,而一个类只能有一个父类。子接继承父类中所有的常量和方法
  • 方法定义的格式为:
  • returnType methodName([paramlist])
  • 接口中只进行方法的声明,而不提供方法的实现,所以,方法定义没有方法体,且用分号(;)结尾。在接口中声明的方法具体有public和abstract属性,所以定义的时候这两个关键词是可以省略的
  • 如果接口中定义了和父类接口同名的常量或相同的方法,则父接口中的常量被隐藏,方法被重载

接口的实现

  • 在类中可以使用接口中定义的常量

接口类型

  • 接口可以作为一种引用类型来使用。任何实现该接口的类的实例都可以存储在该接口类型的变量中,通过这些变量可以访问类所实现的接口中的方法。Java运行时系统的确定该使用那个类中的方法
  • 把接口作为一种数据类型可以不需要了解队形所对应的具体类

接口中的常量

  • 接口体中可以包含常量定义
  • 常量定义的格式为: type NAME = value;
  • 其中type可以是任意类型,NAME 是常量名,通常用大写,value 是常量值
  • 在接口中定义的常量可以被实现该接口的多个类共享
  • 在接口中定义的常量具有 public,static,final的属性

Java8中的接口

  • Java 8 以上,接口成员还可以是:
  • static 方法
  • 具有实现的方法(default方法) 默认方法的好处:提供一个默认实现,子类在implements 可以不用在重复新写了

接口的意义

规范、扩展、回调

抽象类接口区别

	引用于:http://www.jackywang.tech/AndroidInterview-Q-A/chinese/java/%E6%8A%BD%E8%B1%A1%E7%B1%BB%E6%8E%A5%E5%8F%A3%E5%8C%BA%E5%88%AB-360.html

    默认的方法实现 抽象类可以有默认的方法实现完全是抽象的。
    接口根本不存在方法的实现(在Java8 此句描述不准确)

    实现 子类使用extends关键字来继承抽象类。如果子类不是抽象类的话,它需要提供抽象类中所有声明的方法的实现。
    子类使用关键字implements来实现接口。它需要提供接口中所有声明的方法的实现

    构造器
    抽象类可以有构造器
    接口不能有构造器

    与正常Java类的区别
    除了你不能实例化抽象类之外,它和普通Java类没有任何区 接口是完全不同的类型

    访问修饰符
    抽象方法可以有public、protected和default这些修饰符 接口方法默认修饰符是public。你不可以使用其它修饰符。

    main方法
    抽象方法可以有main方法并且我们可以运行它
    接口没有main方法,因此我们不能运行它。

    多继承
    抽象类在java语言中所表示的是一种继承关系,一个子类只能存在一个父类,但是可以存在多个接口。

    速度
    它比接口速度要快
    接口是稍微有点慢的,因为它需要时间去寻找在类中实现的方法。

    添加新方法
    如果你往抽象类中添加新的方法,你可以给它提供默认的实现。因此你不需要改变你现在的代码。
    如果你往接口中添加方法,那么你必须改变实现该接口的类。(在Java8 此句描述不准确)

我是IT小王,如果喜欢我的文章,可以扫码关注我

你可能感兴趣的:(java学习笔记)