java学习(4)——面向对象(上)

第4章  面向对象(上)

4.1   类和对象


4.1.1 定义类

class and object

定义一个类:

[修饰符] class 类名
{
    构造器;
    成员变量;
    方法;
}


修饰符:public、final、abstract

Java类名单词首字母大写,其他字母小写,单词与单词之间没有任何分隔符。

 

构造器

[修饰符] 构造器名(形参列表)

{

   

}

修饰符:public、protected、private

构造器名:与类名相同

 

成员变量(field)

[修饰符] 类型 成员变量名 [= 默认值]

 

修饰符:public、protected、private、static、final

成员变量名:第一个单词的首字母小写,后面每个单词首字母大写,其他字母全部小写

 

方法

[修饰符] 方法返回值类型 方法名(形参列表)

{

   

}

修饰符:public、protected、private、static、final、abstract

方法名:同成员变量名,建议由英文动词开头

 

 

static、类与变量

static修饰的成员不能访问没有static修饰的成员。

static修饰的成员是属于类的,类变量,类方法

没有使用static的:实例变量、实例方法

static的真正作用就是用于区分成员变量、方法、内部类、初始化块这四种成员到底是属于类本身还是属于实例。


public class Person
{
    //成员变量
    publicString name;
    publicint age;
 
    //方法
    publicvoid say(String content)
    {
       System.out.println(content);
    }
}



4.1.2  对象的产生和使用


创建对象的根本途径是构造器,通过new关键字来调用某各类的构造器即可创建这个类的实例。


//  第一种方法

Person p;

p = new Person();


// 第二种方法

Person p = new Person();

 

static修饰的方法和成员变量既可以通过类调用,也可通过方法调用;没有static修饰的方法和成员变量只能通过实例调用。

 


4.1.3  对象、引用和指针

类是一种引用数据类型,如同数组一样。

当一个对象被创建成功后,这个对象将保存在堆内存(heap)中,java不允许直接访问heap中的对象,只能通过该对象的引用p(存储在栈中)操作该对象。

 


4.1.4  对象的this引用

对象的默认引用

this总是指向调该方法的函数:谁在调用this这个方法,this就代表谁。

l  在构造器中

l  在方法中


 

作用:让类中的一个方法,访问该类里的另一个方法或实例。

代码略;

 


特别的:static修饰的方法不能使用this引用,this无法指向有效的对象。


 

如果调用static修饰的成员时省略了前面的主调,那么默认使用该类作为主调;

如果调用没有static修饰的成员是省略了前面的主调,那么默认使用this作为主调。


 

一个典型的错误

public class StaticAccessNoStatic
{
    publicvoid info()
    {
       System.out.println("info");
    }
 
    publicstatic void main(String[] args)
    {
       info();
    }
}

info()方法是属于实例的方法,而不是属于类的方法。

 

注意:Java编程是不要使用对象去调用static修饰的成员变量、方法,而是应该使用类去调用!如果确实需要在静态方法中访问另一个普通方法,则只能重新创建一个对象。

new xx.info();

 

4.2 方法详解


4.2.1  方法的所有属性


4.2.2  方法的参数传递机制


参数传递方法只有一种:值传递

创建一个对象时,系统内存中有两个东西:堆内存中保存对象本身,栈内存保存了引用该对象的引用变量。


4.2.3  形参个数可变的方法


最后一个形参的类型后增加三点(…),则表明该形参可以接受多个参数值,多个参数值被当成数组传入。

形参个数可变的参数本质就是一个数组参数。

对比:

public static void test(int a, String...books);
test(5, "java", "c++","CPP");
 
public static void test(int a, String[]books);
test(5, new String[] {"java","c++", "CPP"});


 

4.2.4  递归方法


4.2.5  方法重载


方法重载的要求就是两同一不同:同一类中方法名相同,参数列表不同。至于方法返回值类型、修饰符等,与方法重载没有任何关系。

不推荐重载的方法里包含长度可变的形参。

 

4.3 成员变量和局部变量


4.3.1  成员变量和局部变量


成员变量是指在类里定义的变量,也就是field;

又分为类变量和实例变量;

 

局部变量是指在方法里定义的变量;

分为形参、方法局部变量和代码块局部变量;


4.3.2  成员变量的初始化和内存中的运行机制


4.3.3  局部变量的初始化和内存中的运行机制


4.3.4  变量的使用规则

类成员变量  <   方法局部变量    <   代码块局部变量

尽可能的缩小作用范围

 


4.4 隐藏和封装


4.4.1  理解封装

该隐藏的隐藏,该暴露的暴露。

 

4.4.2  使用访问控制符

private:当前类访问权限

default:包访问权限

protected:子类访问权限

public:公共访问权限

 

如果一个java源文件里定义的所有类都没有使用public修饰,则这个java源文件的文件名可以是一切合法的文件名;但如果一个java源文件里定义了一个public修饰的类,则这个源文件的文件名必须与public修饰的文件名相同。

 

访问控制符的使用原则:

l  类的大部分成员变量都应该使用private修饰,只有一些static修饰的。类似全局变量的成员变量才可能考虑public修饰。工具方法应该使用private修饰。

l  如果某个类主要是作为其他类的父类,该类包含的大部分方法可能仅希望被其子类重写,而不是调用,则应该使用protected修饰这些方法。

l  希望暴露出来给其他类调用的方法应该使用public修饰。特别是类的构造器,还有外部类。

 

4.4.3  package、import和import static

java引入包机制,提供类的多层命名空间,用于解决命名冲突、类文件管理等问题。java允许将一组功能相关的类放在同一个package下,从而组成逻辑上的类库单元。

package packageName;


一旦在java源文件中使用了package语句,意味着该源文件里定义的所有类都属于这个包,位于包中的每个类的完整类名都应该是包名和类名的组合(lee.Hello.java)。

java的包机制需要两个方面的保证:


1. 源文件里使用package语句指定包名;

2. class文件必须放在对应的路径下。


包名要求全是小写字母。

如果没有显示指定package语句,则处于默认包下,同一个包下的类可以自由访问,无需前缀。

父包和子包存在逻辑上的关系(模块与整体),但在用法上不存在任何关系,如果父包中需要使用子包中的类,则必须使用子包的全名,而不能省略父包部分。

 

使用不同包中的其他类要加全名???


java引入了import,import可以向某个java文件中导入指定包层次下某个类或全部类。

import package.subpackage…ClassName;

ex:

importlee.sub.Apple;
importpackage.subpackage…*;


java默认导入了java.lang下的所有类。


静态导入:用于导入指定类的某个静态成员变量、方法或全部静态成员变量、方法,使用import static语句。(类变量、类方法)


ex:
import static package.subpackage…ClassName.fieldName| methodName;
import static package.subpackage…ClassName.*;

import可以省略写包名,而import static则可以连类名都省略。

 

4.4.4  java的常用包

java.lang
java.util
java.net
java.io
java.text:格式化
java.sql
java.awt:Abstract Windows Toolkits
java.swing:GUI

 

4.5 深入构造器


4.5.1使用构造器执行初始化


4.5.2  构造器重载


多个构造器的形参列表不同,称之为构造器重载。

构造器必须使用new关键字来调用。

构造器B必须完全包含构造器A,如果存在这种关系,则可以在方法B中使用this关键字调用方法A。


一小段代ex:

public Apple(String name, String color,double weight)
{
       this(name,color);
       this.weight= weight;
}

使用this调用另一个重载的构造器只能在构造器中使用,而且必须作为构造器执行的第一条语句。

 

4.6    类的继承


4.6.1  继承的特点


java的继承通过extends关键字实现。子类不能获得父类的构造器。

语法格式如下

修饰符 classSubClass extends SuperClass
{
       //  定义类部分
}<span style="font-family: 'Microsoft YaHei'; background-color: rgb(255, 255, 255);"> </span>

java没有多重继承,只有单继承。

 

4.6.2  重写父类的方法


子类重写父类的方法。鸟能飞,鸵鸟不能飞,只能跑。

方法重写/方法覆盖:子类覆盖父类的方法。


原则:两同两小一大

两同:方法名相同,形参列表相同;

两小:子类方法返回值类型小于等于父类的,子类方法抛出的异常类应小于等于父类的;

一大:子类方法的访问权限应比父类的更大或相等。


覆盖的方法和被覆盖的方法,要么都是实例方法,要么都是类方法(static)。


子类对象无法访问父类中被覆盖的方法,但可以通过super(被覆盖的是实例方法)或父类类名(被覆盖的是类方法)在子类对象中调用该方法。


父类方法具有private访问权限,则该方法对子类隐藏,子类可以另行定义同名方法。


比较

overload:重载,同一类的多个同名方法名之间

override:覆盖,重写,子类和和父类同名方法之间

 

4.6.3  super限定

通过super调用被覆盖的是实例方法,添加一个方法即可。

public void callOverridedMethod()
{
       super.xx();
}


super用于限定对象调用从父类继承得到的实例变量或方法。super不能出现在static修饰的方法中,这一点和this一样。

子类定义与父类同名的实例变量,子类会隐藏父类实例变量()还为它分配内存,而不是重新赋值。

 

4.6.4  调用父类的构造器

类似于一个构造器调用另一个重载的构造器,但是是使用super完成的。

父类构造器先于子类构造器执行,java.lang.Object构造器最先执行。

public Sub(double size, String name, Stringcolor)
{
       super(size,name);
       this.color= color;
}


4.7 多态


4.7.1  多态性


如果编译时类型和运行时类型不一致,就可能出现多态(Polymorphism)。

BaseClass ploymophicBc = new SubClass();


//有限地执行子类,父类到子类,将复杂的东西简单处理。

向上转型(upcasting):将子类对象直接赋值给一个父类引用变量

编译时类型是BaseClass而运行时类型是SubClass。


方法具有多态性,而对象的实例变量并没有具有多态性,对于book,程序中输出的并不是SubClass的实例变量,而是BaseClass的实例变量。


引用变量编译时只能调用其编译时具有的方法,但运行时则执行它运行时类型所具有的方法。通过引用变量来访问器包含的实例变量时,系统总是试图访问它编译时类型所定义的成员变量,而不是运行时类型所定义的成员变量。

 

4.7.2  引用变量的强制类型转换()


子类到父类不担心。

引用变量的类型转换与4.7.2正好相反,是由父类到子类,由简单到复杂。

l  基本类型转换只发生在数值类型之间,boolean只占一位,big太低。

l  引用类型之间的转换发生在在家族内,使用不慎会有ClassCastException异常。


使用instanceof运算符判断是否可以成功转换。

if (objPri instanceof String)
{
    Stringstr = (String)objPri;
}


4.7.3  instanceof运算符


instanceof运算符的前一个操作数通常是一个引用类型变量,后一个操作数通常是一个类(或者接口),它用于判断前面的对象是否是后面的类、子类、实现类的实例,前后一般应该具有父子关系


System.out.println("字符串是否是Comparable接口的实例:"+ (hello instanceofComparable));

 

4.8 初始化块


4.8.1  使用初始化块


初始化块是java中可以除成员变量,构造器和方法的第四种成员(没用的),隐式执行,全部执行。


当java创建一个对象时,系统先为该对象的所有实例变量分配内存(该类已经被加载过了),接着程序开始对这些实例变量执行初始化:先执行初始化块,声明时指定的初始值,再执行构造器。

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值