黑马程序员——面向对象<二> 笔记第四篇
来源:互联网 发布:java超市管理系统 编辑:程序博客网 时间:2024/04/30 20:43
Static关键字、单例设计模式、继承、抽象类
-----Java培训、Android培训、期待与您交流! -------
5 Static 关键字
5.1 Static 的访问方式
static修饰成员变量:static修饰的成员变量的数据就是共享的数据。
static修饰的成员变量(静态的成员变量)的访问方式:
方式1:可以使用对象访问。
对象.属性名
方式2: 可以使用类名访问。
类名.属性名。
注意:
1.非静态的成员变量只能使用对象进行访问,不能使用类名直接访问。
2.千万不要为了方便访问数据而使用static修饰,只有数据真正是需要被共享的时候才使用static修饰。
推荐使用:类名直接访问。
static修饰函数:
静态函数的访问方式:
访问方式1:使用对象访问。
对象.函数名()
访问方式2: 使用类名访问
类名.函数名();
5.2静态函数要注意的细节:
1. 静态函数可以使用对象或者类名调用,但是非静态函数只能使用对象进行调用。
2. 静态函数不能出现this与super关键字。
原因:静态函数是可以使用类名直接调用的,而this关键字代表的是所属函数的调用者对象,这时候可能还没有对象的存在。
3. 静态函数可以直接访问静态的成员(成员变量、成员函数),但是不能直接访问非静态的成员。
原因:非静态的成员变量是随着 对象的创建而存在的,静态函数是可以使用类名直接调用的,这时候可能还没有对象存在。
4. 非静态的函数是可以直接访问静态、非静态的成员的。
原因: 非静态函数是需要对象调用的,对象存在的时候静态 数据以及非静态数据都已经存在了,所以可以。
什么时候使用static去修饰一个函数呢?
如果一个函数没有直接访到非静态的成员,那么即可使用static修饰。常见的应用在:工具类的方法。
疑惑:静态的函数不能访问非静态的成员?
错误,只要静态函数中存在着的对应的对象那么即可访问。
5.3非静态成员变量与静态的成员变量的区别:
作用上的区别:
1. 非静态成员变量的作用:描述一类事物的属性。
2. 静态的成员变量作用: 提供了一个共享的数据给所有对象使用。
数量上的区别:
1.非静态的成员变量是随着对象的创建而 存在的,有 多少个对象就有多少份非静态的成员变量数据。
2. 静态的成员变量数据在内存中仅有一份。是所有对象共享的数据。
生命周期的区别:
1. 非静态的成员变量是随着对象的创建而存在,随着对象的消失而消失。
2. 静态的成员变量数据是随着类文件的加载而存在,随着类文件的消失而消失。
5.4例子:
class Student{
int id; //身份证
String name; //名字
//使用static修饰的数据就是共享的数据,可以被所有的Student对象共享使用,在内存中只有一份。
static Stringcountry ="中国";//国籍
//构造函数
public Student(intid, Stringname){
this.id =id;
this.name =name;
}
//学习
public void study(){
System.out.println("好好学习,为称为高富帅做准备!!");
}
}
class Demo5
{
public static void main(String[] args)
{
Student s1 = new Student(110,"小强");
Student s2 = new Student(119,"小红");
s1.country ="小日本";
System.out.println("身份证:"+s1.id+"名字:"+s1.name+"国籍:"+s1.country); //小日本
System.out.println("身份证:"+s2.id+"名字:"+s2.name+"国籍:"+s2.country); //小日本
}
}
分析:国籍没有static修饰时,运行结果是:(因为此时不是共享的数据)
//身份证:110名字:小强国籍:小日本
//身份证:119名字:小红国籍:中国
6 单例设计模式
解决的问题:保证一个类在内存中的对象唯一性。
比如:多程序读取一个配置文件时,建议配置文件封装成对象。会方便操作其中数据,又要保证多个程序读到的是同一个配置文件对象,就需要该配置文件对象在内存中是唯一的。
6.1 饿汉单例模式:
1. 私有化构造函数。
2. 在本类中创建该类的对象,并且使用一个私有静态的变量指向。
3. 提供有一个公共静态的方法获取本类的对象。
6.2懒汉单例设计模式:
1. 私有化构造函数。
2. 声明本类的引用类型变量,但是不创建本类的对象。
3. 提供一个公共静态的方法获取本类的对象,获取对象之前先判断是否已经创建了该类的对象,如果没有创建,那么创建该类的对象并返回,如果已经创建了该类的对象,那么就直接返回即可。
推荐使用 : 饿汉式。
因为懒汉式有可能出现线程安全问题,这是时候就无法保证该类在内存中只有一个对象了。
6.3 实现的代码
//懒汉式
class Single2{
//声明本类的引用类型变量,但是不创建本类的对象。
private static Single2 s;
//私有化构造函数
private Single2(){}
//提供有一个公共静态的方法获取本类的对象
public static Single2 getInstance(){
if(s==null){
//没有创建就先创建本类对象
s = new Single2();
}
returns;
}
}
//饿汉式
class Single{
//声明本类的引用类型变量指向本类的对象。
private static Single s = new Single();
//第一步:私有化构造函数
private Single(){}
//提供有一个公共静态的方法获取本类的对象
public static Single getInstance(){
returns;
}
}
class Demo10
{
public static void main(String[] args)
{
Single2 s1 = Single2.getInstance();
Single2 s2 = Single2.getInstance();
System.out.println("两个对象是同一个吗?"+ (s1==s2));//true
}
}
7 继承
继承的格式:
class 类名1 extends类名2{
}
继承的特点
1:描述类和类之间的关系
2:降低类和类之间的重复代码
3:降低对象和对象之间的代码重复使用静态变量
4:降低类和类之间的代码重复使用就继承
继承的好处
继承的出现提高了代码的复用性。
继承的出现让类与类之间产生了关系,提供了多态的前提。
继承要注意的细节:
1. 千万不要为了减少重复代码而去继承,只有两种事物真正存在着继承关系的时候才去继承。
2. 父类私有的成员不能被继承。
3. 父类的构造函数不能被继承。
4. 创建子类对象时,会先调用父类的构造函数。
疑惑:为什么创建子类对象的时候会先调用父类的构造函数呢,这样子做的意义在那?
意义就是:初始化从父类继承下来的属性。
7.1 super关键字:
super关键字代表的是父类空间的引用。
7.1.1 super关键字的作用:
1. 子父类存在着同名的成员时,在子类默认是访问子类的成员,可以通过super关键字指定访问父类的成员。
2. 创建子类对象时,默认是会先调用父类无参的构造方法,可以通过super关键字指定调用父类其他的构造方法。
3、主要存在于子类的方法中,用于指向子类对象中父类对象
7.1.2 super关键字要注意的细节:
1. 如果子类的构造函数没有指定调用父类构造函数,那么java编译器会在子类的构造函数中加上super();
2. super 调用父类的构造函数的时候必须是在构造函数中的第一个语句。
3. this 与super关键字调用构造函数时,不能同时出现在一个构造函数中,因为两个都需要在第一个语句。
7.1.3 super关键字与this关键字的区别:
1. super关键字只能在继承的关系下才能使用,this关键字不需要继承照样可以使用。
2. super关键字代表的是父类空间的引用。this代表的是所属函数的调用者对象。
3. super在子类的构造函数中是调用父类的构造函数,this关键字是构造函数中是调用本类的构造函数
4. super可以用作区分同名的子父类成员,可以指定访问父类的成员。 this关键字是用作区分同名的成员变量与局部变量的。
super思考
如果开发者自定义了一个类,没有显示的进行类的继承,那么该类中成员函数是否可以使用super关健健字?可以使用,继承了Object类,Object类是所有类的父类。
class Demo7 {
public void print(){
System.out.println(super.toString());//继承了Object类
}
public static void main(String[] args){
new Demo7().print();
System.out.println();
}
}
小知识点
子类对象查找属性或方法时的顺序:
1:原则:就近原则。
如果子类的对象调用方法,默认先使用this进行查找,如果当前对象没有找到属性或方法,找当前对象中维护的super关键字指向的对象,如果还没有找到编译报错,找到直接调用。
重载和重写的不同
1:重载(overload):
1:前提: 所有的重载函数必须在同一个类中
2:特点:
函数名相同,参数列表不同,与其他的无关(访问控制符、返回值类型)
3:不同:
个数不同 、 顺序不同、 类型不同
2:重写(override):
1:前提:继承
2:特点:
函数名必须相同、参数列表必须相同。
子类的返回值类型要等于或者小于父类的返回值
7.2 instanceof 关键字
作用: 判断一个对象是否属于指定的类别。
使用前提: 判断的对象与指定的类别必须要存在着继承或者是实现的关系。
instanceof 使用格式:
对象instanceof 类
//动物类
class Animal{
String name;//名字
String color;//颜色
//构造方法
public Animal(Stringname,Stringcolor){
this.name =name;
this.color =color;
}
}
//狗 是属于动物中的一种
class Dog extends Animal{
public Dog(Stringname ,Stringcolor){
super(name,color);
}
//咬人
public void bite(){
System.out.println(name+"狠狠的咬人!!");
}
}
//鱼也是属于动物中的一种
class Fish extends Animal {
//构造方法。
public Fish(Stringname,Stringcolor){
super(name,color);
}
public void swing(){
System.out.println(name+"在水里游....");
}
}
class Demo8
{
public static void main(String[] args)
{
Animal a = new Animal("动物","黑色");
Dog d = new Dog("哈士奇","白色");
System.out.println("动物都属于狗类吗?"+(ainstanceof Dog));
System.out.println("狗是属于动物类别吗?"+(dinstanceof Animal)); // 判断对象是否属于狗类型,如果是返回true,否则返回false.
}
}
7.3 final 关键字
作用:增强数据的安全性。
1. final修饰一个基本类型的变量时,该变量不能重新赋值。
2. final 修饰一个引用类型变量时,该变量不能重新指向新的对象。
3. fianl 修饰一个方法的时候,该方法不能被重写。
4. fianl 修饰一个类的时候,该类不能被继承。为最终的类
常量的修饰符: public static final
常量的命名规范:全部字母大写,单词与单词之间使用下划线分隔。
final class Circle{ //狗剩
public static final double PI = 3.14 ; //PI的值应该是固定的。
//半径
int r;
public Circle(intr){
this.r =r;
}
public Circle(){}
//获取面积
public final void getArea(){
System.out.println("面积是:"+PI*r*r);
}
}
class Demo extends Circle //final 修饰的类不能被继承
{
public static void main(String[] args)
{
//创建一个圆形对象。
final Circlec =new Circle(4);
test(c);
/*
c.PI = 0.0; // 狗娃
c.getArea();
//System.out.println("Hello World!");
*/
}
public static void test(Circle c){
//让c变量重新指向一个新的对象。
c = new Circle(5);
}
}
8 抽象类
8.1抽象类的应用场景:
描述一类事物的时候,发现该类事物目前确实存在着某种行为,但是目前这种行为是不具体的,那么这时候我们可以把这种行为描述抽象的行为,只抽取这种行为功能的声明,而不实现该功能行为,这时候我们可以使用抽象类描述。
抽象类的好处:强制子类去实现指定的方法。
抽象类主要为了提高代码的复用性,让子类继承来使用。
8.2抽象类要注意的细节:
1. 如果一个类有抽象的方法,那么该类就必须使用abstract修饰。
2. 非抽象类继承抽象类的时候,必须要把抽象类的所有抽象方法实现。(抽象方法具体化)
3. 抽象类可以存在非抽象方法与抽象方法的。
4. 抽象类可以不存在抽象的方法。
5. 抽象类不能创建对象。
疑问:为什么抽象类不能创建对象呢?
抽象类如果创建了对象,抽象类就调用对应的方法了,抽象类是具有抽象方法的,如果调用了抽象的方法(抽象方法内没有具体功能),这样子是没有意义的。
6. 抽象类是存在构造函数的。
疑问:抽象类不能创建对象,那么存在构造函数的意义何在呢?
抽象的构造函数是提供给其子类使用的,因为需要初始化从父类继承下来的属性数据。
8.3 abstract与其他修饰符的关系:
final与abstract不能共存:
final:它的作用 修饰类代表不可以继承 修饰方法不可重写
abstract修饰类就是用来被继承的,修饰方法就是用来被重写的。
Static static修饰的方法可以用类名调用,
对于abstract修饰的方法没有具体的方法实现,所有不能直接调用,也就是说不可以与static共存。
private
private修饰的只能在本类中使用,
abstract方法是用来被子类进行重写的,有矛盾所有不能共存.
//动物类
abstract class Animal {
String name ;
String color;
//构造函数
public Animal(Stringname ,Stringcolor){
this.name =name;
this.color =color;
}
//跑 抽象的方法
public abstract final void run(); //抽象的行为。 加final修饰后的方法不能被重写
//非抽象的方法。
public void eat(){
System.out.println("吃粮食..");
}
}
//狗 非抽象类
class Dog extends Animal{
//构造函数
public Dog(Stringname,Stringcolor){
super(name,color);
}
public void run(){ //run方法被final修饰
System.out.println(name+"四条腿跑得很快...");
}
}
//鱼 非抽象类 抽象类
class Fish extends Animal{
public Fish(Stringname,Stringcolor){
super(name,color);
}
public void run(){ //run方法被final修饰
System.out.println(name+"摇摇尾巴游啊游!!...");
}
}
class Demo10
{
public static void main(String[] args)
{
/*
//System.out.println("Hello World!");
//创建一个狗对象
Dog dog = new Dog("牧羊犬","棕色");
dog.run();
//创建一个鱼对象
Fish f = new Fish("锦鲤","金色");
f.run();
*/
//创建一个抽象类的对象。
//Animal a = new Animal("动物","黑色");
//a.run();
}
}
- 黑马程序员——面向对象<二> 笔记第四篇
- 黑马程序员——面向对象(二)
- 黑马程序员—java面向对象二
- 黑马程序员—面向对象(二)
- 黑马程序员——面向对象笔记
- 黑马程序员——面向对象<一> 笔记第三篇
- 黑马程序员——面向对象<三> 笔记第五篇
- 黑马程序员——面向对象<四> 笔记第六篇
- 黑马程序员——Java要点笔记——面向对象(二)
- 黑马程序员—面向对象
- 黑马程序员—面向对象
- 黑马程序员—面向对象
- 黑马程序员——JAVA面向对象(二)
- 黑马程序员——day07面向对象(二)
- 黑马程序员——面向对象(二)
- 黑马程序员——面向对象(二)
- 黑马程序员——面向对象(二)
- 黑马程序员—OC—面向对象(二)
- C++ 单例模式的实现
- 【Vijos1790】拓扑编号
- Android TextPaint 写文字 水平、垂直居中
- 2014/11/6
- 第三章总结
- 黑马程序员——面向对象<二> 笔记第四篇
- atitit。gui 界面皮肤以及换肤总结 java .net c++
- Unity3D学习之第三日(前面学习的总结,做了一个小项目)
- 程序员是否优秀的重要因素之一
- 三角形
- POJ 题目2299 Ultra-QuickSort(树状数组求逆序对)
- Atitit.软件gui按钮and面板---通讯子系统(区)-- github 的使用....
- 直方图、基数、选择性
- Django models笔记