Java_面向对象相关(总览及突破)
2017-03-26 19:31
183 查看
Java面向对象重难点与细节部分总结
对象的创建
设有类class A{},产生对象的代码为
new A();,这句的含义是根据类模板产生一个对象,并在计算机内存中为为此对象开辟一块新的独立内存空间。new 操作是栈中创建对象,复制到堆中以类为模板产生对象,实质上就是将类中的属性复制到生成的对象中,这些属性虽然在类中定义,但实际上是为对象服务,因此称他们为对象属性。而方法在调用时,系统会为方法开辟一个栈空间,用于存放方法中的局部变量和形式参数,并且方法在执行的时候还可以访问复制到对象中的属性,其效果就像方法也被复制到对象中一样。方法执行完毕后,栈空间被释放。虽然方法在类中定义但由于可以访问对象属性,故实质还是为对象服务,因而成为对象方法。那么究竟什么能成为类方法呢,下面介绍。
插播:这也就涉及到了Java中的内存分配
堆在应用程序生命周期中一直存在,栈在方法调用完毕后就释放
内存中的分配方法(一部分)。
堆 | 栈区 | 方法区(一说归在栈区) |
---|---|---|
对象(使用new关键字产生的) | 堆中对象的引用(地址) | 静态变量和常量池 |
null | 方法执行时用的局部变量和形参 | 包括(基本类型)常量和字符串常量 |
插播2:C++ new细节
C艹中用关键字new方式产生的对象在堆中,用
A a;产生的对象在方法栈中。还有写法
A* a=new A();。
两种区别:
分配释放方式不同,存放位置也不同
1) 编译器安排代码,自动分配释放,
1.1)全局对象 (全局外部变量,名空间内外部变量,某文件静态变量,类静态变量,函数静态变量,匿名名空间变量),内存为全局(态)数据区
1.2)函数内非静态变量对象,内存为栈区
代码:
A a; // 自动分配,并在合适的时候释放 a.print(); //操作
2)程序员写出代码,主动分配释放内存。
内存包括,两部分
2.1)有名对象 指针变量 a ,和 上面一样,自动分配。
2.2)无名对象 *a ,内存在堆区,这部分主动分配释放
代码
A *a=new A(); //分配内存 a->print(); //操作 delete a; //释放
对象*a 是无名对象,通过有名对象 指针 a 进行操作;
前面我们通过
new A();有了对象,接下来还想要对它进行控制。
A a;的作用是产生一个A类的声明,此时并没有任何此类的对象产生,也没有为对象分配内存。这是与C艹不同的,C艹中此时已经有对象了。 Java中我们需要将
A a;与对象连在一起才能通过a控制生成的对象,使用
a=new A();。更直接的方法是
A a=new A();一步到位。
A a=new A();过程是先产生对象再将对象赋予声明a。当a被赋予对象后,就从概念‘声明’升级为概念‘引用’。
static
static修饰的方法有如下特点:static方法是类方法,但可以被所有对象所访问,引用这个方法时,可以使用对象名做前缀,也可以使用类名做前缀。
static方法内部的代码,只能访问类中的static属性或方法,不能访问类中的非static属性或方法(因为那是对象方法),但非 static方法(对象方法)可以访问static数据成员。
main方法是特殊的静态方法,是Application程序入口点,必须写成public static void main(String args[])的形式
static修饰的方法是类方法,修饰的属性是类属性。其他的方法都称为对象方法,为对象服务。static修饰的类由于只能访问类的static属性而不能访问对象中的属性,故称为【真!类方法】
static方法调用时,也开辟栈空间存放局部变量
static类“对象共同拥有”,可以直接通过[类名.方法]调用方法,不必实例化对象。
参数传递
借用我老师的一句话:Java中所有的参数传递都是值传递,也就是拷贝传递。就算是对象的“引用传递”也是值传递,只是拷贝的是地址。//普通数据类型作为参数传递是值传递,对象"引用传递"是拷贝地址传递,归根结底也是值传递。 //就算是静态类函数修改静态类属性,一样是拷贝 public class X { private static int a; public static void main(String [] args) { modify(a); System.out.println(a); } public static void modify(int a) { a++; } } 本程序的输出为0,因为a++是对形式参数进行自增,而不是对对象属性a进行自增。
看下面的一个例子
class IntClass{ int value; } public class RunIntClass { public static IntClass getInstance(){ //在方法中产生对象 IntClass s= new IntClass();//2 s.value=8; return s; } public static void main(String args[]){ IntClass a; a = getInstance(); //1 System.out.println(a.value); //3 } } /** *在main方法中使用的对象是在getInstance方法当中产生并放到堆中(用new长生的放在堆中), *再通过引用s将对象地址返回赋值给a,此时getInstance方法所在的占空间被释放,s也被释放但 *对象在堆中还没消失,现在由a指向这个对象。 */ //程序输出:8
使用C艹编写上面的RunIntClass函数时,如果将IntClass s= new IntClass();换为IntClass s;程序会出错i,因为这种方式产生的对象在方法栈中,若仅仅将引用传回,随着栈空间的释放对象也就消失了。
如果用String去修改上面的程序,观察是否能够调用?【因为String很特别,可以直接赋值】
public class RunIntClassUseString { public static String getInstance(){ //在方法中产生对象 String s="abc"; //String s= new String();//2 //s="abc"; return s; } public static void main(String args[]){ String a;//此时a是null不是“”,此句分配了一个内存空间,没存入任何对象,相当于什么也没做。 //String a="";会分配一个内存空间并存入一个字符串对象! //但C艹中使用string a;已经分配好空间创建了对象.类比前面C艹A a;的栗子 //Java这时再跟一句a=new string("abc")将会把栈中的对象复制进堆。 a = getInstance(); //1 System.out.println(a); //3 } }
静态代码块
一个类中可以使用不包含在任何方法体中的静态代码块。当类被装载时,静态代码块被执行且只被执行一次。静态代码块经常用来对类中定义的属性进行初始化class Test { static int value ; static { value = 3; System.out.println("value="+value); } public static void main(String[] args){ } } //程序输出结果为3
多态:重载与覆盖
重载:类中定义了多个同名而不同内容参数的成员方法,成这些方法为重载方法 overloading覆盖:子类对父类参数相同,返回类型相同的同名方法重新进行定义这种多态成为覆盖 overriding
方法名称相同,参数名称相同,返回类型相同:覆盖
方法名称相同,参数名称不同:重载
方法名称相同,参数名称相同,返回类型不同:编译不能通过
覆盖——注意
子类的访问修饰符权限应等于或大于父类
static方法不能覆盖非静态方法,也不能被非static方法覆盖,但是static方法可以覆盖static方法
方法前有final修饰符,此方法不能在子类方法中进行覆盖
在JDK中,很多父类的方法被子类重新覆盖,赋予了不同的含义,如Object类中的boolean equals(Object obj)方法
抽象类中如果存在抽象方法,则具体子类必须对抽象方法进行覆盖
抽象类
抽象类不可以有对象,抽象类存在就是为了被继承。所以自编的父类多数时候都应为抽象类,不然则认为设计有问题。(父类上面还有父类时可不作为抽象类)抽象类中不可以有private成员
如果子类还是抽象类,则子类不可以定义和父类重名的抽象方法。
如果把抽象类写成
abstract public double area(){}这不叫抽象类,有了{}就是实现,空着也是实现。
在抽象类中,非抽象方法可以调用抽象方法。
abstract不能与final并列修饰同一个类(产生逻辑矛盾);
abstract 不能与private ,static(因为static修饰的方法必然被直接调用),final或native并列修饰同一个方法
接口
就是特殊的抽象类(纯虚类) 所有方法都是abstract通俗地讲就是不同类的相同行为的集合
定义接口要注意几点
接口定义用关键字interface,而不是用class,interface前的修饰符要么为public,要么为缺省。
接口定义的数据成员全是final static(静态常量)。即使没有修饰符,其效果也等效,访问级别要么为public,要么为缺省。
接口中没有构造方法;所有成员方法都是抽象方法(与抽象类有所不同)。即使没有修饰符,其效果完全等效,访问级别要么为public,要么为缺省。注:方法前不能修饰为final。
接口具有继承性,可通过extends关键字声明接口的父接口
此文为总览及突破, 细节部分见log2000计划之类与对象系列博文
visitor tracker相关文章推荐
- Java之面向对象相关问题集
- java--流程控制、数组、面向对象相关备忘知识点
- java面向对象相关——聊聊多态
- 黑马程序员_java面向对象相关 个人理解
- Java之面向对象相关问题集
- Java-阶段小结笔记(六)--面向对象相关
- 了解java面向对象相关基础基础_final知识
- java笔记--Day07--面向对象基础(相关概念)
- java面向对象相关概念
- 黑马程序员_Java基础Day06_面向对象静态相关内容(Done)
- JAVA学习第2天 面向对象相关概念
- 面向对象题目,经典点的(java的 也可以用c#做下)
- java和c++在面向对象上有什么区别?
- Java三个月 - 面向对象程序设计OOP的乐趣 - 程序人生
- 面向对象程序设计--C++/Java
- 深入Java面向对象预备篇(3.研究数组)
- Java面向对象继承与组合的问题
- 面向 Java 开发人员的 Ajax: Ajax 的 Java 对象序列
- 面向Java开发人员的Ajax:Ajax的Java对象序列化
- 面向对象与上帝造人——类与对象(java篇)