`

【笔记】面向对象

 
阅读更多

        封装:形式上是将数据和行为组合在一个包中,并对对象的使用者隐藏数据的实现方式。

 

        构造器用来构造和初始化对象。

               Date deadline;     //定义了一个对象变量,可以引用Date对象,这里没有引用任何对象

        deadline是变量,不是对象。由于目前没有引用对象,所以执行deadline.toString会编译错误。

               deadline=new Date();

               Date birthday=deadline;    //这两个变量引用了同一个对象

         一个变量并没有实际包含一个对象,而是仅仅引用一个对象。Java的对象变量可以看做是C++中的指针,所有的java对象都存储在堆中,当一个对象包含另外一个对象变量时,这个变量依然可以认为是指向另外一个堆中的对象的指针。

 

         不要编写返回引用可变变量的访问器方法。

class Employee{
    private Date hiredate;
    Date getHiredate(){
          return hiredate;
    }
}

Employee harry=...;
Date d=harry.getHireDate();
d.setTime(......);  //变量d所指向的Date(也就是harry所指对象的私有域hire达特)发生了改变

          如果需要返回可变对象的引用,那么应该使用clone。

class Employee{
    private Date hiredate;
    Date getHiredate(){
          return (Date)hiredate.clone();
    }
}

 

        方法可以访问其所在类的私有特性

boolean equals(Employee other){
    return name.other.name;
}

 

         类的final实例域必须保证构造器执行完之后它已被初始化,且以后不能对其修改。

 

calss Employee{
    private final String name;
}

          final一般修饰基本数据类型或者不可变类的域。对于可变的类,final修饰可能引起混乱。例如:private final Date hiredate; 这仅仅意味着hiredate引用的对象不能改变,而并不意味这这个对象的状态不能改变,类中的任何方法都可以调用hiredate.setTime()来修改hireDate的状态。

 

         静态域属于类的,不属于任何对象。private static int nextId=1;

         静态变量使用较少,但静态常量使用比较多。public static final double PI=3.1415;

         System.out就是一个静态常量。System类内部有public static final PrintStream out=......;

         静态方法是类方法,它不能操作对象,不能访问除静态域以外的实例域。

 

         java中方法的参数传递采用值调用进行的。对象变量传递参数实际是将实参(指针)赋值给形参。

 

         如果构造器、初始化块等地方没有初始化变量,那么变量会自动赋值为0,false,null。

         如果没有构造器,那么系统会构造一个默认构造器,进行默认初始化。如果类中有构造器,但是没有提供默认构造器,那么调用e=new Employee();会出错。

         调用同一类中另外一个构造器用this(... ...);调用父类中的构造器用super(... ...);

 

         java初始化顺序:父类静态变量—>父类静态代码块—>子类静态变量—>子类静态代码块—>父类非静态变量—>父类非静态代码块—>父类构造方法—>子类非静态变量—>子类非静态代码块—>子类构造方法。

        静态代码块会在类第一次加载时进行初始化。以下代码输出:2B31CA31CA

public class F {
	public F(){
		System.out.print("1");
	}
	static{
		System.out.print("2");
	}
	{
		System.out.print("3");
	}
}

 

public class S extends F{
    public S(){
    		System.out.print("A");
    }
    static{
		System.out.print("B");
	}
	{
		System.out.print("C");
	}
}

 

public class FSTest {
	public static void main(String[] args){
		F t=new S();
		t=new S();
	}
}

 

 

 

 

继承示例:

 

public class Employee {
    private double salary;
    public Employee(double salary){
    	this.salary=salary;
    }
    public double getSalary(){
    	return salary;
    }
    public void setSalary(double salary){
    	this.salary=salary;
    }
}
 
public class Manager extends Employee{
    private double bonus;
    public Manager(double salary,double bonus){
    	super(salary);
    	this.bonus=bonus;
    }
    @Override
    /*这里不能用salary+bonus,因为Manager没有显示的域salary,也不能直接访问父类的私有
     * 域salary,只有Employee类的变量所指的对象才能访问salary;也不能用getSalary()
     * +bonus,这样调用的不是Employee类的getSalary而是Manager类的getSalary(自己的)
     * ,这样会不断调用自己的方法;用super调用父类的方法
     */
    public double getSalary(){
    	return super.getSalary()+bonus;
    }
    @Override
    public void setSalary(double salary){
    	super.setSalary(salary);
    }
     public double getBonus(){
         rreturn bonus;
     }
}
 
public class EmployeeTest {
	public static void main(String[] args) {
		Employee boss=new Manager(5000,1000);
		System.out.println(boss.getSalary());
		boss.setSalary(7000);
		System.out.println(boss.getSalary());
	}
}
 

 

        如果子类的构造器没有显式的调用父类的构造器,那么子类会自动调用父类的默认构造器。如果父类没有默认构造器,且子类没有显式的调用父类的构造器,那么编译出错。

 

        this引用隐式参数,调用该类的构造器;

        super调用父类方法,调用父类构造器。

 

        覆盖一个方法时,子类方法的可见性不能低于父类方法的可见性。父类为public,子类必须是public。

 

        Employee boss=new Manager(5000,1000);

        boss.getSalary();    //得到6000

        这里boss声明为Employee类但是实际引用了Manager类,在执行时它会调用Manager类的getSalary犯法。

        一个对象变量可以引用多种类型的对象的现象称为多态。运行时它能自动选择调用哪个方法,这种现象称为动态绑定。

        Manager boss=new Manager(5000,1000);        Employee staff=boss;    //Employee类型变量staff指向了boss对象,staff和boss指向同一个变量

        可以调用boss.getSalary,但是不能调用staff.getBonus,因为编译器认为staff是Employee变量。

调用staff.getSalary时会动态绑定到Manager类的getSalary方法。

 

        Manager m[]=new Manager[10];

        Employee s[]=manager;  //这个是合法的,因为每个m[i]是Employee对象。

        s[0]=new Employee(... ...);  //编译器接受了,s[0]是Employee变量

        但是,s[0]和m[0]指向了同一个对象像,这导致m[0]指向了一个Employee对象,当调用m[0].getBonue()会出错 。

         所以,对于数组类型的数据,要牢牢记清楚自己的类型,插入元素时候必须要保证兼容性。如果将Employee对象插入m[0]所指向的位置时候应该抛出异常。

 

        动态绑定:

        编译器查看对象的声明类型和方法名。通过声明类型找到方法列表。
       编译器查看调用方法的参数列表。(方法的名称和参数列表称为方法的签名)。
       如果方法是private、static、final或者构造器,编译器就可以确定调用那个方法。这就是静态绑定。

        否则就要使用运行时(动态)绑定。采用动态绑定意味着:虚拟机将调用对象实际类型的方法。
         动态绑定的过程:虚拟机提取对象的实际类型的方法表;虚拟机搜索方法签名;
调用方法。在多态的情况下,虚拟机可以找到所运行对象的真正类型。

 

        一个类用final修饰后就不能被扩展。方法被final修饰就不能就不能被覆盖。

 

        类型转换的目的是在忽略对象的实际类型后,使用对象的全部功能。类型转换只能限定在继承层次内进行。在使用转换之前应该用instanceof进行类型的检查。instaceof只会返回false而不会抛出异常。

        if(staff instaceof Manage){

                 boss=(Manager)staff;

          }

 

        抽象类的成员可以具有访问级别,而接口的成员全部public级别
        抽象类可以包含字段,而接口只能定义常量
        抽象类的成员可以具有具体实现(非抽象方法),而接口不行
        抽象类可以有构造方法,接口中不能有构造方法
        抽象类中可以包含静态方法,接口中不能包含静态方法
        一个类可以实现多个接口,但只能继承一个抽象类

 

         访问级别:

         private——仅仅本类可见

         public——对所有类可见

         protected——对本包及子类可见

         默认——对本包可见

 

        所有类的超类Object:

                1、Object类型的变量可以引用任何类型的对象,例如Object obj=new int();

                2、equals方法。原型是public boolean equals(Object obj){this==obj;}

class Employee{
    ... ...
public boolean equals(Object other){  //注意啊,这里参数是Object
        if(this==other) return true;  //两者地址相同
        if(other==null) return false;  //参数地址为空
        if(getClass!=other.getClass())  //两者类型不同
               return false;
         Employee ot=(Employee)other;
        return name.equals(ot.name)&&salary==ot.salary;
    }
}

 

class Manager extends Employee{
    .... ...
public boolean equals(Object other){
        if(!super.equals(other))  return false; //作为Employee必须先相等
        return  bonus==((Manager)other).bonus;
   }
}

          3、hashCode方法。散列码是对象导出的一个整数值,散列码没有规律。equals方法与hashCode方法必须保持一致:x.equals(y)为true,那么x、y的hashCode()应该一样。String的hash如下:

int hash=0;
for(int i=0;i<length();i++)
    hash=31*hash+charAt(i);

          4、toString方法,用来返回字符串,方便对象之间的+操作。

          5、clone方法。它是Object类的protected方法。对象拷贝是让两个变量引用同一个对象,任何一个变量都可以引起对象的状态改变。对象克隆是将一个变量引用的对象的副本让另外一个变量来引用。克隆分深克隆和浅克隆。默认是浅克隆,也就是将对象的状态(全部数据域)拷贝给副本。

      但是如果对象包含了对象的引用,当这种对象是不可变的,不会有任何问题,但是如果这种对象是可变的,那么,这会导致两个变量所指的对象的引用型数据域指向了同一个可变对象。这是就应该进行深克隆了,这需要自己进些覆盖重写clone方法(实现Cloneable接口)。

 

           接口用来描述类有什么功能,而不具体实现每个功能。接口不是类,而是类的一组需求的描述。一个类可以实现多个接口。接口中的所有方法自动属于public,因此接口声明中不必提供关键字public接口中能够定义常量。接口不能有实例域,也不能在接口中实现方法。

 

 

       接口不是类,所以不能用new来操作。但是可以声明接口型的变量,这个变量必须引用实现了接口的类对象。   Comparable x=new Emplyoyee();

 

       多个无关的类可以实现同一个接口,一个类可以实现多个接口。通过接口可以了解对象的交互界面,而不需要了解对象的类。

 

       可以用instanceof检查一个对象是否属于某个特定的类,也可以用instance检查一个对象是否实现了某个特定的接口:  if(anObj instanceof Comparable){... ...}

 

          接口可以扩展。接口可以有常量,不能有实例域或者静态域。

 

public interface Movable{
     void move(double x,double y);
}

public interface Powered{
     double milesPerGallon();
     double SEED_LIMIT=95;    //它会自动变成public static final型的
}
 
       回调是指某个特定事件发生时应该采取的动作。

 

 

      内部类方法可以访问该类定义所在的作用域中的数据,包括私有域。

      内部类可以对同一个包中的其他类隐藏。

      当定义一个毁掉函数且不想编写大量代码时,可以使用匿名内部类

 

 

public class A {
	private int s=111;
	private class B{
		private int s=11;
		public void show(int s){
			System.out.println(s);//局部
			System.out.println(this.s);//内部类
			System.out.println(A.this.s);//外层类
		}
	}

	public static void main(String[] args){
		A a=new A();
		A.B b=a.new B();  //内部类的引用方式:OuterClass.InnerClass
		b.show(1);
	}
}

 

    局部内部类不仅可以完全的隐藏自己,还可以访问局部变量,不过局部变量要声明为final型的。如果一个内部类不用命名,就可以使用匿名内部类。

public void start(int interval, final boolean beep){    //内部类可以使用beep,不能用interval
      ActionListener listener=new ActionListener(){ 
           public void actionPerformed(ActionEvent e){
                    Date now=new Date();
                    System.out.println("time:"+now);
                    if(beep)           //内部类使用beep
                          Toolkit.getDefaultToolkit().beep();
            }
      }
       Timer t=new Timer(interval,listener);
        t.start();
}

 

      

 

 

 

 

分享到:
评论

相关推荐

    php笔记 面向对象

    面向对象编程是PHP中一种重要的编程范式,它允许开发者以更加抽象和模块化的方式组织...在上述示例中,`Man`和`Car`类的组合展示了类之间的交互,`hit()`方法改变了`Man`对象的`$iq`属性,体现了面向对象编程的动态性。

    Python全栈学习笔记面向对象大作业:校园管理系统

    校园管理系统 角色: 学校、学员、课程、讲师 要求: 1. 创建北京、上海 2 所学校 2. 创建linux , python , go 3个课程 , linux\py 在北京开, go 在上海开 3. 课程包含,周期,价格 ...4. 班级关联课程、讲师 ...

    Java面向对象-笔记.docx

    Java面向对象笔记 面向对象是一种编程思想,Java是一种面向对象的编程语言。下面是Java面向对象笔记的知识点摘要: 一、类和对象 * 对象:对象是一个实体,由一组属性和方法构成。对象的属性是对象具有的各种特征...

    C#面向对象笔记

    C#面向对象笔记 C#中的面向对象编程是一种编程范式,强调模块化、继承、多态和封装。面向对象编程的三大特征是: 1. 封装:是指隐藏类或模块的内部实现细节,从而实现数据的保护和访问控制。封装的类或模块尽量只...

    面向对象学习笔记

    ### 面向对象学习笔记 #### PHP5面向对象基础 **1.1 类和对象** 面向对象编程(Object-Oriented Programming, OOP)是一种软件开发范式,其核心思想是将现实世界中的事物抽象成类(Class),然后根据类创建具体的...

    Java学习笔记-面向对象-001-面向对象概括

    面向对象编程(Object-Oriented Programming,简称OOP)是一种重要的编程范式,它基于对象的概念,通过将数据和操作数据的方法封装在一起,提供了一种更高效、灵活且可维护的编程方式。Java语言作为一门纯面向对象的...

    Java 面向对象笔记

    Java面向对象编程是Java语言的核心特性,它使得代码更加模块化、可维护,易于扩展。以下是对Java面向对象主要知识点的详细阐述: 1. **对象和类**:在Java中,一切皆为对象,对象是类的实例。类是创建对象的模板,...

    PHP_OOP面向对象课堂笔记

    PHP_OOP面向对象课堂笔记,最简洁明白易懂的面向对象笔记,欢迎下载!

    面向对象程序设计C++听课笔记

    本篇笔记基于中山大学博士的视频讲授和浙江大学副教授的课堂记录,旨在深入浅出地解析C++中的面向对象特性。 一、C++简介 C++是C语言的扩展,由Bjarne Stroustrup在1983年创建,增加了类、模板、异常处理等面向对象...

    JAVA的面向对象编程笔记(经典)

    Java面向对象编程笔记 本文主要介绍了Java面向对象编程的基本概念和原则,包括对象、类、继承、多态、封装、抽象等概念的定义和解释,并通过实例讲解了面向对象编程的思想和方法。 一、什么是对象? 在面向对象...

    苏坤《面向对象》视频教程笔记

    笔记文档“苏坤《面向对象》视频教程笔记.docx”应该是对课程内容的详细记录,包括重要概念的解释、代码示例和关键点的总结。通过阅读这份笔记,可以巩固课堂所学,加深对面向对象编程的理解。 总之,面向对象编程...

    Java学习笔记(必看经典)

    JAVA的面向对象编程--------课堂笔记 面向对象主要针对面向过程。 面向过程的基本单元是函数。 什么是对象:EVERYTHING IS OBJECT(万物皆对象) 所有的事物都有两个方面: 有什么(属性):用来描述对象。 能够做...

    java面向对象编程课堂笔记

    面向对象编程是Java的核心特性,它使得代码更加模块化、可维护性和可扩展性更强。在Java中,万物皆对象,即所有的事物都可以抽象成一个对象,对象包含其属性(描述对象的状态)和方法(描述对象的行为)。面向对象...

    面向对象与设计模式基础笔记

    ### 面向对象与设计模式基础知识点梳理 #### 一、面向对象的基本概念 **面向对象编程(Object-Oriented Programming, OOP)** 是一种编程范式,其核心思想是将现实世界中的事物抽象成类(Class),并通过类创建...

    UML-面向对象建模笔记

    **UML(Unified Modeling Language)**,统一建模语言,是一种在...而"友情提示.txt"和"UML面向对象建模笔记"很可能是学习过程中的辅助资料,可能包含了对UML建模的详细解释和实例分析,对于理解和掌握UML非常有帮助。

    韩顺平老师笔记JS面向对象和dom编程笔记

    **JS面向对象编程** JavaScript(JS)是一种广泛用于网页和网络应用的脚本语言,它支持面向...结合韩顺平老师的笔记,这些概念和实践会帮助你深入理解JS面向对象编程和DOM编程,从而更好地构建交互丰富的Web应用程序。

    java 笔记, 讲解多态 面向对象

    ### Java面向对象编程中的多态性详解 #### 一、面向对象编程概述 在Java语言中,面向对象编程(Object-Oriented Programming, OOP)是一种编程范式,它通过将程序分解为一系列相互作用的对象来组织代码。这种方式...

    java面向对象和第一章整理笔记

    Java面向对象编程是Java语言的核心特性,它基于面向对象编程...这些笔记涵盖了Java面向对象编程的基本概念,对于初学者来说,是理解和掌握Java技术的关键。通过深入学习和实践,可以构建出高效、可维护的Java应用程序。

Global site tag (gtag.js) - Google Analytics