文章目录
- 一、面向对象编程三大特性:
- 二、类的建立
- 三、类的UML类图:
- 四、构造方法:
- 五、java参数传递
- 六、对象的组合:
- 七、关联关系与依赖关系:
- 八、实例成员与类成员:
- 八、this 关键字
- 九、Java 包(package)
- 1)、包的作用
- 十、import 关键字
- 十一、打包与JAR文件
- 十二、访问控制
- 十三、可变参数:
- 十四、讨论
- (1)为什么Static 不用this和supper限定
- (2)变量:成员变量和局部变量的初始化
- (3)对象不能作为方法的参数
- (4)static:结果是102
- (5) 输入流使用close 会关闭整个流,下次不能再输入;
- (6)问题1:使用按需导入声明是否会降低Java代码的执行效率?
- (7)问题2:是否意味着你总是可以使用按需导入声明? 说明理由
- (8)修饰符:哪些修饰符可以用于修饰内部类
- (9)修饰符+static:
- (10)在定义变量和方法时,必须清楚地在其面前标上访问权限修饰符。( √)
- (11).构造方法用于给类的private实例变量赋值。(× )
- (12)在类定义中,成员访问权限修饰符不能多次出现。( ×)
一、面向对象编程三大特性:
1、封装: 将相关的数据以及作用在这些数据上的操作组织在一起,实现信息隐藏。
信息隐藏是指对象的某些特征只在对象内部可见;外部程序只能访问那些允许它访问的特征。
2、继承:实现代码复用的有效手段,它将问题域中的泛化关键映射到解空间中。子类中含有父类的 内容(变量和方法)。
3、多态:面向对象编程的重要目标之一是实现程序的独立性,从而提高程序的可扩展性与可复用性。多态性分两种:编译时多态和运行时多态,编译时多态性->方法重载, 运行时多态子类对象转换父类对象的方法重写,是面向对象设计的精华所在。
二、类的建立
(1)public、private、friendly
类是组成Java程序的基本要素,JAVA程序是以类为基本单位进行编译。类封装了同一类型对象的状态和方法。类是用来定义对象的模板。
类的实现包括两部分:类声明和类体。
1、类定义的一般格式:
[修饰符] class 类名 {
[修饰符] 类型 成员变量1;
[修饰符] 类型 成员变量2;
… …
[修饰符] 类型 成员方法名(参数列表){
类型 局部变量;
方法体
}
}
修饰符包括:public,默认(friendly)等2种,如果修饰符是public,那么该文件名一定要用类名命名。 比如:public class Student { } 则该类所在的文件名必须命名为:Student.java
修饰符如果是private、protected,则该类只能做为内部类。
class是关键字,用来定义类。“class 类名”是类的声明部分,类名必须是合法的Java标识符。两个大括号以及之间的内容是类体。
(2)给类命名时,遵守下列编程风格(这不是语法要求的,但应当遵守)
1).如果类名使用拉丁字母,那么名字的首字母使用大写字母,如People、Student等。
2).类名最好容易识别、见名知意。当类名由几个“单词”复合而成时,每个单词的首字母使用大写(骆驼法命名)。
示例:比如定义一个梯形类:
public class Lader{
private float above; //定义梯形上底
private float bottom; //定义梯形下底
private float height; //定义梯形高
public float computerArea(){ //定义方法计算梯形面积
return (above + bottom) * height / 2;
}
public void setHeight(float h){ // 定义方法修改梯形的高
height = h;
}
public static void main(String[] ar){ //main()方法
new Lader().setHeight(5); //创建对象并且调用setHeight()方法
}
}
三、类的UML类图:
UML类图分为三层:名字层、变量层、方法层。如下图:
说明:在UML图中:
‘-’ : 表示访问权限是private
‘+’ : 表示访问权限是public
'#‘ : 表示访问权限是protected
访问权限是友好的(即默认),变量名和方法名前不使用符号。 比如:setHeight()方法
如果是静态方法,则在方法名下用下划线。比如main()方法。
变量定义注意: 提倡一行只声明一个变量。 方便给代码增加注释内容。如上面的lader类中的变量定义。
四、构造方法:
构造方法是一种特殊方法,方法名必须与它所在的类名完全相同,而且没有返回值类型。
比如:Lader(){
}
构造方法的作用:给对象进行初始化,这种初始化动作在new 返回新创建对象的引用前完成。
!!!注意:
1)、构造方法与它要初始化的类同名
2)、构造方法是给对象赋初值,没有返回值
3)、构造方法不能被程序显示调用
4)、构造方法可以有零个或多个自变量
5)、构造方法可以在类中由编程者定义,如果编程者没有定义,系统将自动生成一个构造函数
6)、构造方法可以通过重载实现不同的初始化方法
7)、构造方法可对静态变量(实例变量)初始化
3、创建对象:
创建一个对象包括对象的声明和为对象分配变量两个步骤。
1).对象的声明: Lader lader ;
2). 为声明的对象分配内存: lader =new Lader();
3).对象的内存模型
(1)声明对象时的内存模型
(2)对象分配内存后的内存模型
4).创建多个不同的对象
当对象存在,系统会自动用这个相同的对象,不必再创建新的 (待考证)
String s=“hello”;
String s1 = new String (“hello”);
5)当设置构造函数为为private 或 protected 时
可以采用静态方法调用构造函数
package number;
class Person{
private Person(){// 这里是private 私有类型
System.out.println("hello,java");
}
static Person getPerson(){// 利用静态方法来调用构造函数
Person a= new Person();
return a;
}
}
public class Test {
public static void main(String[] args){
Person p = Person.getPerson();// 这里这么写 new Person(),则会报错
}
}
五、java参数传递
address
结论:
1、基本类型作为参数传递时,是传递值的拷贝,无论你怎么改变这个拷贝,原值是不会改变的
2、对象作为参数传递时,是把对象在内存中的地址拷贝了一份传给了参数。
1) 基本类型作为参数传递时,是传递值的拷贝,无论你怎么改变这个拷贝,原值是不会改变的
示例一:
public class Test1 {
public static void main(String[] args) {
int n = 3;
System.out.println("Before change, n = " + n);
changeData(n);
System.out.println("After changeData(n), n = " + n);
}
public static void changeData(int nn) {
nn ++;
}
}
程序运行结果:
分析:main方法中的n原的值为3,想通过调用changeDate(n)方法将n的值修改,结果发现n的值仍然为3并没有变成4。
2) 当使用对象作为方法的形参时:
示例二:
public class Test1 {
public static void main(String[] args) {
StringBuffer sb = new StringBuffer("Hello ");
System.out.println("Before change, sb = " + sb);
changeData(sb);
System.out.println("After changeData(n), sb = " + sb);
}
public static void changeData(StringBuffer strBuf) {
strBuf.append("World!");
}
}
程序运行的结果:
从结果中可以看到main方法中的对象sb和changeData()方法中的strBuf是同一个对象,strBuf对象内容增加了World,sb对象也增加了World内容。所以是将sb对象的引用传递给了strBuf。
问题扩展:将上面的程序简单的修改成如下的情况,思考结果是什么?
public class Test1 {
public static void main(String[] args) {
StringBuffer sb = new StringBuffer("Hello ");
System.out.println("Before change, sb = " + sb);
changeData(sb);
System.out.println("After changeData(n), sb = " + sb);
}
public static void changeData(StringBuffer strBuf) {
strBuf = new StringBuffer("Hi,"); //增加的语句
strBuf.append("World!");
}
}
输出的结果是:
为什么变成这样,而不是前面的结果呢?原因是在changeData()方法中“strBuf = new StringBuffer(“Hi,”); ”重新分配内存空间,改变了strBuf的内存地址,strBuf不再是和传递过来的sb引用是同一块内存空间了,即在函数changeDate内的变量strBuf 和 在main函数重的strBuf不是同一个。
不理解可以看看下面的例子
(1)、在方法体中没有为形参对象重新分配内存空间,若修改形参指向的数据内容,则会对实参变量的数值产生影响,因为形参变量和实参变量共享同一块堆区;
(2)、在方法体中重新为形参对象重新分配内存空间,若修改形参指向的数据内容,则不会对实参变量的数值产生影响,因为形参变量和实参变量分别指向不同的堆区;
六、对象的组合:
组合就是 B类的对象是A类的成员变量。
简单示例:
class B {
void methodB() {
System.out.println("我是类B的methodB");
}
}
public class A {
B object; //定义成员对象 体现组合。
public A(){
object = new B(); //为成员对象变量分配内存空间
}
void methodA() {
System.out.println("我是类A的methodA");
object.methodB();
}
publicstaticvoid main(String[] args) {
A a = new A();
a.methodA();
}
}
《thinking in Java》里面是这样说的,“composing a new class from existing classes, thisconcept is called composition (if the composition happens dynamically, it’susually called aggregation)”
中文意思是:通过现在的类组合成一个新的类,叫做组合(如果这种组合是动态的,则叫聚合)。如何理解动态的:就是可以随时加进类中,也可以随时从类中删除。
如何理解对象的组合与对象的聚合?
A类中包含B类的一个引用b,当A类的一个对象消亡时,b这个引用所指向的对象也同时消亡(没有任何一个引用指向它,成了垃圾对象),这种情况叫做组合,反之b所指向的对象还会有另外的引用指向它,这种情况叫聚合。
组合和聚合都表示类之间整体和部分的关系,区别在组合关系中部分和整体具有一致的生存期,相互依存,不能独立存在,成员是整体的一部分,整体类可以控制成员类的生命周期,成员类依赖于整体类。否则是聚合。
程序示例:
class Hand{ //定义手类
}
class Address{ //定义地址类
}
组合关系: Hand是Person的一部分,Hand脱离Person就没有意义了。
class Person{
private Hand hand;
public Person(){
hand = new Hand(); //放在构造函数中,hand 声明周期跟person对象一致
}
}
聚合关系: Person有一个Address,Address脱离Person仍然可以单独存在。
class Person{
private Address address;
public setAddress(){
address = new Address(); //放在公有函数
}
}
七、关联关系与依赖关系:
(1)关联关系:
如果类A中有一个或者以上的类B对象作为其成员变量,则类A与类B之间是关联关系,称类A关联于类B。组合与聚合均属于关联关系。
(2)依赖关系:
如果类A中的某个方法的参数是类B的对象,或者方法中有局部变量为类B的对象,或者返回值类型为类B对象,则类A与类B是依赖关系,称类A依赖于类B。
其UML图如下:
八、实例成员与类成员:
1)、实例变量和类变量的区别。
用关键字static修饰的称作类变量,否则称为实例变量。示例:
class Dog{
int age; //实例变量
static int name; //类变量
}
实例变量与类变量的区别:
内存空间上:
- 不同对象的实例变量互不相同,也就是说分配给不同对象的实例变量占有不同的内存空间,改变其中一个对象的实例变量不会影响其他对象的实例变量。
- 所有对象共享类变量,即分配给这些对象的这个类变量占有相同的一处内存,改变其中一个对象的这个类变量会影响其他对象的这个类变量。
访问的权限上:
- 类变量是属于该类的,在类被加载到内存时就为类变量分配了相应的内存空间,故,可通过类名直接访问类变量。
- static 只能访问static 类型
2)、实例方法和类方法
方法类型前加关键字static修饰的称为类方法,否则称为实例方法。
实例方法和类方法区别:
①要用对象调用实例方法。
②可以用对象调用类方法,也可以用类名调用类方法,也就是说不必创建对象就可以直接调用类方法(创建对象会导致类中的实例变量被分配内存空间)。
示例:
???这个例子出了小问题,待纠正或更换
class subClass{
static int classPar;
int instancePar;
static void setclassPar(int i){
classPar=i;
}
void setinstancePar(int i){
instancePar=i;
}
static int getclassPar() {
return classPar;
}
int getinstancePar() {
return instancePar;
}
}
public class MainClass {
public static void main(String args[]) {
subClass obj1=new subClass();
subClass obj2=new subClass();
obj1.setclassPar(5);
obj2.setclassPar(7);
obj1.setinstancePar(3);
obj2.setinstancePar(6);
System.out.println("obj1.classPar:"+obj1.getclassPar());
System.out.println("obj2.classPar:"+obj2.getclassPar());
System.out.println("obj1.instancePar:"+obj1.getinstancePar());
System.out.println("obj2.instancePar:"+obj2.getinstancePar());
}
}
3)、密码锁练习
package day01;
import java.util.*;
// 密码类
class Intial{
String password;
Intial(String str){
password=str;
}
void setPassword(String s) {
this.password = s;
}
String getPassword() {
String s = password;
return s;
}
}
public class Test1 {
static Intial mima= new Intial("1234");
public static void main(String[] args) {
int count=1;
// 初始化密码
if(count==0) {
System.out.println("欢迎首次使用智能锁,你的初始 密码是"+mima.getPassword());
modify();
count++;
}
else if (count ==1){
jadge(mima.getPassword());
count++;
}
}
// 限制密码格式
public static String number() {
String s;
System.out.println("请输入4位密码");
Scanner a= new Scanner(System.in);
s= a.nextLine();
if(s.length()!=4) {
System.out.println("请按正确的密码格式输入");
}
return s;
}
// 判断密码
public static void jadge(String password) {
String s = number();
if(s.equals(password)) {
System.out.println("密码正确,为你成功开锁");
modify();
}
else {
System.out.println("密码错误");
return;
}
}
// 修改密码
public static void modify() {
System.out.println("输入“1”,可以修改密码");
Scanner b = new Scanner(System.in);
int i = b.nextInt();
if(i == 1){
System.out.println("输入你想修改的密码:");
Scanner a = new Scanner(System.in);
String s = a.nextLine();
a.close();// 只需要关闭一个,因为他吧整个控制台关闭了
mima.setPassword(s);
System.out.println("修改成功");
}
else {
System.out.println("错误输入");
return ;
}
}
}
八、this 关键字
是 Java 常用的关键字,可用于任何实例方法内指向当前对象,也可指向对其调用当前方法的对象,或者在需要当前类型对象引用时使用。
this的三种用法:
1) this.属性名;
当方法中的局部变量(形式参数)和成员变量同名时,要用this限定成员变量名。
2) this.方法名
this 关键字最大的作用就是让类中一个方法,访问该类里的另一个方法或实例变量。
大部分时候,一个方法访问该类中定义的其他方法、成员变量时加不加 this 前缀的效果是完全一样的。
省略 this 前缀只是一种假象,虽然程序员省略了调用 jump() 方法之前的 this,但实际上这个 this 依然是存在的。
3) this( )访问本类构造方法
this( ) 用来访问本类的构造方法,括号中可以有参数,如果有参数就是调用指定的有参构造方法。
this( ) 不能在普通方法中使用,只能写在构造方法中。
★在构造方法中使用时,必须是第一条语句。
理解下图的程序:
九、Java 包(package)
为了更好地组织类,Java 提供了包机制,用于区别类名的命名空间。
1)、包的作用
(1)、把功能相似或相关的类或接口组织在同一个包中,方便类的查找和使用。
(2)、如同文件夹一样,包也采用了树形目录的存储方式。同一个包中的类名字是不同的,不同的包中的类的名字是可以相同的,当同时调用两个不同包中相同类名的类时,应该加上包名加以区别。因此,包可以避免名字冲突。
(3)、包也限定了访问权限,拥有包访问权限的类才能访问某个包中的类。
Java 使用包(package)这种机制是为了防止命名冲突,访问控制,提供搜索和定位类(class)、接口、枚举(enumerations)和注释(annotation)等。
包语句的语法格式为:
packagepkg1[.pkg2[.pkg3…]];
示例:packagenet.java.util;
public class Something{ … }
那么它的路径应该是 net/java/util/Something.java
这样保存的。 package(包) 的作用是把不同的java 程序分类保存,更方便的被其他 java 程序调用。
一个包(package)可以定义为一组相互联系的类型(类、接口、枚举和注释),为这些类型提供访问保护和命名空间管理的功能。
以下是一些 Java 中的包:
java.lang-打包基础的类
java.io-包含输入输出功能的函数
2)、创建包
创建包的时候,你需要为这个包取一个合适的名字。之后,如果其他的一个源文件包含了这个包提供的类、接口、枚举或者注释类型的时候,都必须将这个包的声明放在这个源文件的开头。
包声明应该在源文件的第一行,每个源文件只能有一个包声明,这个文件中的每个类型都应用于它。
如果一个源文件中没有使用包声明,那么其中的类,函数,枚举,注释等将被放在一个无名的包(unnamed package)中。
由于包创建了新的命名空间(namespace),所以不会跟其他包中的任何名字产生命名冲突。使用包这种机制,更容易实现访问控制,并且让定位相关类更加简单。
包名不建议用java 、com 、net 、javax等单词开头
示例:
package jcom.packtest;
public classPackageTest {
public void getTest() {
System.out.println("my method isgetTest of package one");
}
public static void main(String []args) {
System.out.println("welcome topackage one");
}
}
3)、运行包
执行下面命令(-d:表示文件路径。点(.):表示当前路径)
javac -d . PackageTest.java
当前文件夹中就会生成一个jcom的文件夹。
然后就会在当前路径生成我们创建的包:jcom.packtest(一个包可以创建多个类,这里是PackageTest类),以及在包中的类:PackageTest.class。
执行下面命令来运行这个类:
java jcom.packtest.PackageTest
十、import 关键字
为了能够使用某一个包的成员,我们需要在 Java 程序中明确导入该包。使用 “import” 语句可完成此功能。
在 java 源文件中 import 语句应位于 package 语句之后,所有类的定义之前,可以没有,也可以有多条,
1)、其语法格式为:
import package1[.package2…].(classname|*);
如果在一个包中,一个类想要使用本包中的另一个类,那么该包名可以省略。
用 import 关键字引入,使用通配符 “*”
import jcom.packtest.*; //引入java jcom.packtest包中程序需要的类
使用 import 关键字引入PackageTest类:
import jcom.packtest.PackateTest; //引入java jcom.packtest包中的PackageTest类
import java.lang.Math.*; //导入Math类中全部静态成员
import java.lang.Math.PI; //导入Math类中静态成员变量PI
import java.lang.Math.cos; //导入Math类中静态方法cos
2)、注意事项:
(1)、类文件中可以包含任意数量的 import 声明。import 声明必须在包声明之后,类声明之前。
(2)、Java 中默认引入的包是:java.lang包。
十一、打包与JAR文件
JAVA程序都是以类的形式存在,存放和运行的时候都比较麻烦,可以使用jar命令将项目进行打包,JAR包是Java中所特有一种压缩文档,可以当作理解成indows中的zip、rar压缩包。并且在Java中提供的内置类都是以包的形式存在,比如我们用java.util包、java.lang包等都是在rt.jar包中。
对于JAVA项目类进行打包的工具和方法较多,在这里介绍两种方法:JAR命令打包和Eclipse项目打包。
1)、JAR命令打包。
例如:
C:\work>jar cvf example.jar DoorLock.class
命令参数如下:
-c 创建一个jar包
-t 显示jar中的内容列表
-x 解压jar包
-u 添加文件到jar包中
-f 指定jar包的文件名
-v 生成详细的报造,并输出至标准设备
-m 指定manifest.mf文件.(manifest.mf文件中可以对jar包及其中的内容作一些一设置)
-0 产生jar包时不对其中的内容进行压缩处理
-M 不产生所有文件的清单文件(Manifest.mf)。这个参数与忽略掉-m参数的设置
-i 为指定的jar文件创建索引文件
-C 表示转到相应的目录下执行jar命令,相当于cd到那个目录,然后不带-C执行jar命令
2)、示例:
(1)、Person.java文件代码如下:
package tt;
public final class Person{
public static int age() {
return 30;
}
}
注意:该文件保存在F:\ch2
文件夹中。
(2)编译Person.java文件,如下图:
(3)用打包Person.class文件,如下图:
(4)、将person.jar文件移动到jdk下的ext文件夹下,如图:
(5)编写MyAge.java文件,代码如下:
import tt.Person;
public class MyAge{
public static void getAge() {
System.out.println(Person.age());
}
public static void main(String[] ar){
new MyAge().getAge();
}
}
注意:该文件保存在F:\ch2文件夹中。
(6)、编译并运行MyAge.java程序,如下图:
3)、jar命令打包成可运行jar文件。
如果要打包成可运行的jar文件,则在jar包中要包含有一个manifest.mf
文件,该文件是用来告诉程序运行的入口,即主类。可以自己建立manifest.mf这个文件(新建一个记事本文件,将其改名成manifest.mf即可),也可以用jar命令(比如:jar cvfm test.jar Test.class)打包自动生成,不过这个manifest.mf文件中没有指明主类。然后我们在manifest.mf文件中添加下面语句:
Mani-Class: MainClass
注意:(1)冒号后面有一个空格
(2)写完MainClass后面不能有空格并且要回车,光标到第二行。
(1)、Jar打包可运行jar文件:
程序代码如下:
package jcom.packtest;
public class PackageTest {
public void getTest() {
System.out.println("my method is getTest of package one");
}
public static void main(String []args) {
System.out.println("welcome to package one");
}
}
(2)、将文件保存在F:\ch文件下,并对其进行编译: javac –d . PackageTest.java
(3)、在F:\ch文件夹下建立manifest.mf文件,其内容如下图:
(4)、运行jar命令进行打包,并运行jar文件如下图:
十二、访问控制
1)、成员变量和成员方法权限修饰符:
public: 该变量可以被任何类访问。
protected:该变量可以被该类及其子类,与该类在同一包中的类访问。
private:该变量只能被该类的方法访问。
default :该变量可以被该类,与该类在同一包中的类访问。
内部类呢用什么修饰??
2)、阅读并理解下面程序
class Tom{
private float weight;
protected int age;
public String name;
public void set(float w,int a,String n){
weight = w;
age = a;
name = n;
}
public void display() {
System.out.println(name + " : " + age + " : " + weight);
}
}
class UseTom{
Tom t = new Tom();
public void use() {
t.age = 15;
t.weight = 30; //不正确
t.name = "Mr_Huang";
}
}
(2)、构造方法的访问权限
构造方法的访问权限可以有以下几种情况:
1、采用 private:一般是不允许直接构造这个类的对象,再结合工厂方法(static方法),实现单例模式。注意:所有子类都不能继承它。
class A
{
public String name;
//构造函数限定为private,不可以直接创建对象
private A()
{
}
//需要创建对象实例时,调用此函数
public static A Instance()
{
return new A();
}
}
class B
{
public static void main(String[] args)
{
A a=A.Instance();
a.name="aaaa";
System.out.println(a.name);
}
}
2、采用 protected :就是为了能让所有子类继承这个类,但是外包的非子类不能访问这个类;
3、采用 public :对于内外包的所有类都是可访问的;
4、缺省的修饰符:本包内所有的类可访问的。
(3)类的封装
所谓封装就是说类的设计者只是为使用者提供类对象可以访问的部分(成员变量和方法),而对于类中其他成员变量和方法隐藏起来,用户不能访问。
JAVA的类都采用这种数据隐藏机制和封装机制。这样让用户不必要知道程序实现的细节,只要知道类可以访问的部分就可以了。增强数据安全性。
封装指以下几个方面:
1)、在类的定义中设置对对象中的成员变量和方法进行访问的权限。
2)、提供一个统一供其他类引用的方法。
3)、其他对象不能直接修改本对象所拥有的属性和方法。
如何进行数据的隐藏和封装呢?
JAVA中对数据的隐藏和封装是通过用户的访问权限来实现的。
十三、可变参数:
在JAVA语言中,可以将同一个类中多个方法名相同、参数类型相同、返回类型相同,仅仅是参数个数不同的方法抽取成一个方法,这种方法称为可变参数的方法。
从JDK5.0开始支持可变参数的特性。
1)、语法形式:
修饰符 返回类型 方法名(参数类型... 参数名){
}
double max(double… num){
double maxValue = num[0];
for (int i = 1;i < num.length;i++){
if (num[i] > maxValue){
maxValue = num[i];
}
}
}
注意:使用时,将可变长度的参数,当做数组使用,等价于:
修饰符 返回类型 方法名(参数类型[] 参数名){
… …
}
2)、使用特点:
(1)、可变参数的实参可以为0个或任意多个,当为0个参数时传入长度为0的数组:double[0]
(2)、可变参数的实参可以为一维数组类型
(3)、可变参数和普通类型参数 一起使用时,只能放在最后
(4)、一个参数列表中至多有一个可变参数!
3)、示例:
public class VarargsDemo {
public static void main(String args[]) {
printMax(34, 3, 3, 2, 56.5); // 调用可变参数的方法
printMax(new double[]{1, 2, 3,20});
printMax();
}
public static void printMax( double... numbers) {
if (numbers.length == 0) {
System.out.println("No argument passed");
return;
}
double result = numbers[0];
for (double n : numbers){
if (n > result) {
result = n;
}
}
System.out.println("The max value is " + result);
}
}
4)可变参数和数组的区别
可变参数其实就是数组,但是它比数组强大些
比如:int...num
num.add();
可变参数是可以调用方法实现功能
而数组是不行的
5)可变参数的方法可以不可重载?
十四、讨论
(1)为什么Static 不用this和supper限定
1、static修饰的方法体属于类本身
2、this限定符代表的是当前类的实例
3、supper限定符代表的是当前类的父类的实例
4、static修饰的方法和变量在被编译时被初始化,被称为类级变量(属于类)
5、this和super限定符代表的是实例,是在程序运行时被初始化,被称为对象级变量(属于对象)
6、在程序执行过程中,二者不处于同一时间点
(2)变量:成员变量和局部变量的初始化
★成员变量会被系统默认初始化,局部变量没这功能,所以必须自己初始化。
还要注意静态成员变量也没系统默认初始化,必须在初始化块或者定义时或者构造函数里进行手动初始化
(3)对象不能作为方法的参数
(4)static:结果是102
1.class HasStatic{
2. private static int x=100;
3. public static void main(String[ ] args){
4. HasStatic hs1=new HasStatic( );
5. hs1.x++;
6. HasStatic hs2=new HasStatic( );
7. hs2.x++;
8. hs1=new HasStatic( );
9. hs1.x++;
10. HasStatic.x--;
11. System.out.println(“x=”+x);
12. }
13. }
(5) 输入流使用close 会关闭整个流,下次不能再输入;
(6)问题1:使用按需导入声明是否会降低Java代码的执行效率?
不会的
import java.util.Date:称为单类型导入,又称精确导入
import java.util.*;称为按需类型导入
(7)问题2:是否意味着你总是可以使用按需导入声明? 说明理由
是,但也不全是!
然而,有这四个理由让你可以放弃这种声明:
- 编译速度:在一个很大的项目中,它们会极大的影响编译速度.但在小型项目中使用在编译时间上可以忽略不计。
- 命名冲突:解决避免命名冲突问题的答案就是使用全名。而按需导入恰恰就是使用导入声明初衷的否定。
- 说明问题:毕竟高级语言的代码是给人看的,按需导入看不出使用到的具体类型。
- 无名包问题:如果在编译单元的顶部没有包声明,Java编译器首选会从无名包中搜索一个类型,然后才是按需类型声明。如果有命名冲突就会产生问题。
(8)修饰符:哪些修饰符可以用于修饰内部类
以下哪些修饰符可以用于修饰内部类MyInner? (多选)
public class MyClass{
public static void main(String[] ar){
class MyInner{ }
}
}
A、public
B、static
C、friend
D、private
(9)修饰符+static:
读程序,以下可以在main()方法中添加的语句是哪些?(多选)
class Test{
private float f = 1.0f;
int m = 12;
static int n = 1;
public static void main(String[] ar){
Test t = new Test();
//... ...
}
}
(5.0分)
A、t.f // 看漏眼了,因为他现在还处在自己类里面,所以可以调用
B、this.n
C、Test.m
D、Test.n
(10)在定义变量和方法时,必须清楚地在其面前标上访问权限修饰符。( √)
(11).构造方法用于给类的private实例变量赋值。(× )
设置方法用于给类的private实例变量赋值。
(12)在类定义中,成员访问权限修饰符不能多次出现。( ×)
可以,且出现顺序不限