java基础(二):面向对象
来源:互联网 发布:php 对象类型 编辑:程序博客网 时间:2024/05/05 21:59
一、成员变量和局部变量
成员变量:作用于整个类中,存在于堆内存中,因为对象的存在,才在内存中存在。
局部变量:作用于函数中,存在于栈内存中
二、封装
封装:是指隐藏对象的属性和实现细节,仅对外提供公共的访问方式
好处:
将变化隔离,便于使用,提高重用性,提高安全性
封装原则:
将不需要对外提供的内容都隐藏起来
把属性隐藏,提供公共方法对其访问
private修饰词修饰(权限修饰符,只能在本类中访问),提供get,set方法。用于修饰成员变量和成员函数。提高代码健壮性
构造函数
特点:函数名与类名相同,不用定义返回值类型,不可以写return语句
构造函数是在对象已建立就运行,给对象初始化,一个对象建立,构造函数只运行一次
作用:给对象初始化
注意:多个构造函数是以重载的形式存在的,
构造代码块:
作用:给对象进行初始化,对象一建立就运行,优先于构造函数执行
和构造函数的区别:构造代码块是给所有对象进行统一初始化的,而构造函数是给对应的对象初始化的。
注意:当一个类中每一个构造函数都要执行相同的初始化动作时,可以将这个初始化动作放到构造代码快中执行
this关键字 :
用于区分局部变量和成员变量同名的情况
this代表本类对象,代表它所在函数所属对象的引用
哪个对象在调用this所在的函数,this就代表哪个对象
this语句(this(name);):用于构造函数间的调用,this语句只能放在构造函数的第一行
//例:class Person{ private String name; private int age; Person(){} Person(String name){ this(); this.name = name; } Person(String name,int age){ this(name); this.age = age; }}
原因:假如在定义name的时候初始化了,private String name = "李四";
构造函数:
Person(String name){
this.name = name;
this();
}
new Person(“张三”);
一创建对象,会先给name属性赋值“张三”,然后再进行属性的显示初始化“李四”
取得时候就取不到你初始化的值了。
被修饰后的成员具备以下特点:
随着类的加载而加载
随着类的消失而消失,说明它的生命周期最长
优先于对象存在
静态优先存在,对象后存在
被所有对象共享
可以直接被类名调用
注意:
静态方法只能访问静态成员
静态中不能写this和super关键字
主函数是静态的
调用方式:类名.静态成员。
实例变量和类变量的区别
1、存放位置:类变量随着类的加载而存在于方法去中
实例变量随着对象的建立而存在于堆内存中
2、生命周期
类变量生命周期最长,随着类消失而消失
实例变量生命周期随着对象的消失而消失
优缺点:
优点:对对象的共享数据进行单独空间的存储,节省空间,可以直接被类名调用
缺点:生命周期过长,访问出现局限性
主函数:
是一个特殊的函数,作为程序的入口,可以被jvm调用
主函数的定义:
public:代表该函数的访问权限最大
static:主函数随着类的加载就存在了。
void:没有返回值类型
main:不是关键字,是个特殊的单词,可以被jvm识别
(String[] args):函数的参数,
格式固定:被jvm识别
静态的使用:
当方法不访问非静态成员变量时,可将方法静态化,
静态代码块:
只执行一次,优先主函数执行用于给类初始化对象创建过程:new一个对象:Person p = new Person();
1、jvm加载类(Person.class)进内存,
2、静态代码块执行,
3、堆中开辟空间,分配内存地址值
4、在堆内存中简历对象的特有属性,并进行默认初始化
5、显示初始化(定义属性的时候赋的值),
6、对对象进行构造代码初始化,
7、构造函数初始化
8、将内存地址值赋给栈内存中的p变量;
被静态修饰的(成员方法或成员变量)优先对象存在于方法区中
//单例(static关键字的使用之一)://饿汉式:public class Single { private Single() {} private static Single s = new Single(); public static Single getInstance() { return s; } }//懒汉式:public class Single { private Single() {} private static Single s = null; public static Single getInstance() { if (s == null) { synchronized(Single.class) { if (s == null) {s = new Single(); } } } return s; }}
java中的方法重写
什么是方法的重写:
如果子类对继承父类的方法不满意,是可以重写父类继承的方法的,当调用方法时会优先调用子类的方法。
重写方法必须和被重写方法具有相同方法名称、参数列表和返回类型。
重写方法不能使用比被重写方法更严格的访问权限(由于多态)。
继承的初始化顺序
先初始化父类再初始化子类;
先执行初始化对象中的属性,再执行构造方法中的初始化。
java中的final关键字的使用
final关键字做标识有“最终的”含义。
final可以修饰类、方法、属性和变量。
1.修饰类:则该类不允许被继承;
2.修饰方法:则该方法不允许被覆盖(重写);
3.修饰属性:则该类的属性不会进行隐式的初始化(类的初始化属性必须有值)或在构造方法中赋值;
4.修饰变量:则该变量的值只能赋一次值,即为常量。
Java中的super关键字的使用
super关键字:在对象的内部使用,可以代表父类对象。
super的应用
1.子类的构造过程当中必须调用其父类的构造方法。
2.如果子类的构造方法当中没有显示调用父类的构造方法,则系统会默认调用父类无参的构造方法(通过super关键字)。
3.如果显示的调用构造方法,必须写在子类的构造方法的第一行(super();)。
4.如果子类构造方法中既没有显示调用父类的构造方法,而父类又没有无参的构造方法,则编译出错。
java中的Object类
Object类是所有类的父类,如果一个类没有使用extends关键字明确标识继承另外一个类,那么这个类默认继承Object类。
Object类中的方法,适合所有子类。
几个重要的方法
1.toString()方法: 在Object类中定义toString()方法的时候,返回的是对象的哈希code码(对象地址字符串)。 可以通过重写toString()方法表示出对象的属性。
2.equals()方法: 比较的是对象的引用是否指向同一块内存地址。
抽象练习2:模板方法模式
/** 雇员示例: * 需求:公司中程序员有姓名,工号,薪水,工作内容。 * 项目经理除了有姓名,工号,薪水,还有奖金,工作内容。* 对给出需求进行数据建模。* 分析:* 在这个问题领域中,先找出涉及的对象。 * 通过名词提炼法。 * 程序员: 属性:姓名,工号,薪水、 * 行为:工作。 * 经理: 属性:姓名,工号,薪水,奖金。* 行为:工作。 * 程序员和经理不存在着直接继承关系, 但是程序员和经理却具有共性内容。* 可以进行抽取。因为他们都是公司的雇员* 可以将程序员和经理进行抽取.建立体系.*///描述雇员。abstract class Employee {private String name;private String id;private double pay;Employee(String name, String id, double pay) {this.name = name;this.id = id;this.pay = pay;}public abstract void work();// getter setter}// 描述程序员。class Programmer extends Employee {Programmer(String name, String id, double pay) {super(name, id, pay);}public void work() {System.out.println("programmer work");}}// 描述经理。class Manager extends Employee {private int bonus;Manager(String name, String id, double pay, int bonus) {super(name, id, pay);this.bonus = bonus;}public void work() {System.out.println("manager work");}// getter setter}
static关键字:用于修饰成员(成员变量和成员函数)
三、继承
特点:
类是对对象的抽象,继承是对某一批类的抽象,从而实现对现实世界更好的建模。提高代码的复用性。子类继承父类,可以得到父类的全部属性和方法(除了父类中的构造方法)。
java中只有单继承,没有像c++那样的多继承。多继承会引起混乱,使得继承链过于复杂,系统难于维护。
java中的多继承可以通过接口来实现。
提高代码复用性,让类之间产生关系,多态的体现,只支持单继承(接口支持多继承)
//例:class A{void show(){}}class B{void show(){}} class c extends A,B{}class Test{public static void main(String[] args){new C().show();//这里就挂了,不知道调用那个方法了}}
重写(函数):
与父类方法同名,同返回值类型,同形式参数,访问权限等于或者大于父类方法的权限,静态只能覆盖静态
重载和重写的区别:
重载:只看同名函数的参数列表重写:子父类方法要一样(除了里面的逻辑代码)
super的用法,调用父类一般函数:super.函数名;调用父类构造函数:super();
super语句必须定义在子类的第一行;
子类构造函数中super和this语句只能只有一个;
子类的所有构造函数都会默认访问父类的空参数构造函数(子类所有构造函数第一行都有一句隐式的super();)
父类中没有空参数的构造函数时,子类必须显示的通过super语句访问父类的构造函数
子类中至少会有一个构造函数访问父类的构造函数
问:为什么super和this在构造函数中只能写第一行
因为初始化动作要先执行
四、抽象
特点:
抽象方法一定在抽象类中。抽象方法和抽象类都必须被abstract关键字修饰
抽象类不能创建对象
抽象类中的方法要被使用,必须有子类复写所有的抽象方法后建立自雷对象调用,如果子类只覆盖了部分抽象方法,那么子类还是一个抽象类
抽象练习:
/* * 需求:获取一段程序运行时间 * 原理:获取程序开始和结束时间并相减 */abstract class GetTime {public final long getTime() {long start = System.currentTimeMillis();runCode();long end = System.currentTimeMillis();return end - start;}public abstract void runCode();// 让子类做想做的事情,不一定要抽象,可以有默认的方法}class SubTime extends GetTime {@Overridepublic void runCode() {// 方法内的代码自定义try {Thread.sleep(5245);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("SubTime");}public static void main(String[] args) {SubTime st = new SubTime();System.out.println(st.getTime());}}
接口:
定义:当抽象类的方法都是抽象的,那么这个类可以通过接口的形式来表示
class:用于定义类
interface用于定义接口
子类必须全部覆盖接口方法才能实例化
一个类可以实现多个接口(就算两个接口中有相同的抽象方法【完全相同,包括返回值和方法名】也可以),并且可以同时实现继承
接口和接口之间可以实现多继承(注意:当两个接口中有两个抽象方法的方法名相同但是返回值不同的时候,这两个方法要符合重载的形式否则编译失败)
//例:interface A {public abstract int show();}interface B {public abstract double show();}interface C extends A,B{//此时,编译失败//如果A接口和B接口方法名相同,那么可以将两个抽象方法定义到一个接口里,使用重载的形式使其存在}
接口定义的格式特点:
接口中常见的定义:常量,抽象方法,静态方法(jdk8才有)
接口中的成员都有固定的修饰符:
常量:public static final 类型 名称(名称所有字母大写)
方法:public abstract 返回值 方法名();
静态方法:public static 返回值 方法名() {}
接口的使用:
类实现接口使用implements关键字,支持类多实现接口,但是只能单继承,如果这个类没有全部实现接口的方法,则这个类是抽象类
接口之间的继承使用extends关键字,接口之间支持多继承。
接口的特点
接口是对外暴露的规则
接口是程序的功能扩展
接口可以用来多实现
类与接口之间是实现关系(implements),而且类可以继承一个类的同事实现多个接口
接口和接口之间可以有多继承关系
五、多态
体现:
父类引用指向了自己的子类对象父类的引用也可以接受自己的子类对象
前提
必须是类与类之间有关系,要么继承要么实现通常还有一个前提:存在覆盖
好处
多态的出现大大的提高了程序的扩展性弊端
提高了扩展性,但是只能使用父类的引用访问父类中的成员//Animal a = new Cat(); //类型提升,向上转型
如果想要提升类型,向下转型 Cat c = (Cat)a;
多态中成员的特点:
在编译时期:参阅引用型变量所属的类中是否有调用的方法。如果有编译通过,没有则编译失败在运行时期:参阅对象所属的类中是否有调用的方法
简单总结就是:成员函数在多态调用时,编译看左边,运行看右边
多态中,成员变量的特点:无论编译还是运行,都参考左边(引用型变量所属的类)
多态中,静态成员函数的特点:无论编译,运行,都参考左边
- Java基础 (二)(面向对象)
- java面向对象基础小结(二)
- Java基础之面向对象(二)
- Java基础—面向对象(二)
- Java基础<六>----面向对象(二)
- JAVA基础(二)面向对象思想
- java基础之面向对象(二)
- java基础(二):面向对象
- Java面向对象基础二
- Java面向对象基础(二)
- 【java基础 二】---面向对象思想(基础)
- 面向对象基础(二)
- 面向对象基础(二)
- JAVA基础篇二(Java,C++中的面向对象)
- 四.Java基础_面向对象(二)
- java基础(二)流程控制与面向对象
- 黑马程序员----Java基础(六):面向对象之二
- java基础——面向对象(二)
- Sql中sum()函数和group by 函数的使用
- HDU 2222 AC自动机 解题报告
- CSS声明
- BZOJ 4870 HEOI 2017 组合数问题
- Apache日志文件大小管理设置分析方法
- java基础(二):面向对象
- 1028. List Sorting (25)
- 为什么数据库连接很消耗资源
- 斯坦福大学公开课机器学习课程(Andrew Ng)六朴素贝叶斯算法
- 【数据结构】中判断一棵树是否为平衡二叉树
- 剑指offer面试题[60]-将二叉树打印成多行
- java小程序(万年历)
- Struts-2.0标签,关于ajax标签那些事儿.....
- 战胜拖延症