尚学堂--面向对象1
1、成员变量
- 成员变量可以不初始化,系统默认对其初始化
- 局部变量必须初始化
2、引用
- 基础类型(4类8种):占一块内存
- 引用类型 :占两块内存
类是静态概念,代码区
对象是new出来的,位于堆内存(堆内存是动态分配内存,只有在运行过程中才会new一个对象放在堆内存中,这个对象占用多大内存我们
提前不知道,所以没办法提前分配,只能在运行期间去分配它(敲javac xx.java执行是在编译期间,敲java xx执行是在运行期间))类的每个成员变量在不同的对象中有不同的值(除了静态变量),但是方法只有一份,执行的时候才占用内存
3、类和对象的关系
4、构造方法
- 使用new + 构造方法 创建一个新的对象
- 构造方法与类同名且没有返回值
- 当你没有指定构造函数时,编译器为类自动添加形如 类名(){ } 的构造函数,但是一旦定义自己构造方法后,系统便不再添加
class Person { int id; int age; Person(int _id, int _age) { id = _id; age = _age; } }
5、内存分析(尚学堂面向对象06、07、08节视频)
方法执行完毕之后,为这个方法分配的所有局部变量的内存空间全部消失(栈中内存立刻消失,堆中内存可能不是立刻消失,需要等待垃圾收集器回收)
6、方法重载
方法的重载是指一个类中可以定义相同的名字,但参数不同的多个方法。调用时,会根据不同的参数列表选择相对应的方法
构造方法也可以重载
7、this关键字
this一般出现在方法里面,当方法还没调用的时候this指向谁并不知道,当我们new一个对象出来的时候,this就是指向当前这个对象
执行return的时候会在栈空间临时分配一块内存
1 public class Leaf { 2 int i = 0; 3 Leaf(int i) { 4 this.i = i; 5 } 6 Leaf increament() { 7 i ++; 8 return this;//执行return,在栈空间分配临时内存指向this的内容,this指向它自身,所以临时内存也指向了它 9 } 10 void print() { System.out.println("i = " + i); } 11 12 public static void main(String[] args) { 13 Leaf leaf = new Leaf(100); 14 leaf.increament().increament().print();//返回i = 102 15 } 16 }
8、static关键字
- 在类中,用static声明的成员变量为静态成员变量,它为该类的公有变量,在第一次使用时被初始化,对于该类的所有对象来说,static成员变量只有一份
- 用static声明的方法为静态方法,在调用该方法时,不会将对象的引用传递给它,所以在static方法中,不可访问非static的成员。静态方法不再针对于某个对象调用,所以不能访问非静态成员
- 可以通过对象引用或类名(不需要实例化)访问静态成员
1 public class Cat { 2 3 private static int sid = 0; 4 private String name; 5 int id; 6 7 Cat(String name) { 8 this.name = name; 9 id = sid++; 10 } 11 12 public void info() { 13 System.out.println("My name is " + name + "No." + id); 14 } 15 16 public static void main(String[] args) { 17 Cat.sid = 100; 18 Cat mimi = new Cat("mimi"); 19 Cat pipi = new Cat("pipi"); 20 mimi.info();//输出:My name is mimiNo.100 21 pipi.info();//输出:My name is pipiNo.101 22 } 23 }
9、package和import语句(同目录import就行,不同目录需修改CLASSPATH到包的位置(如com.bjsxt.java140的com目录(不包含com)),再import)
- 如果想将一个类放入包中,在这个类源文件第一句话写package(注释除外)
- 必须保证该类的.class文件位于正确目录下
- 该类的源码可能会产生影响
- 删除会转移到另外的目录(即下面例子中的Cat.java文件不能放在Dog.java同目录下(已删除,原Cat.java和Dog.java均在Dog.class同目录下))
- 该类的源码可能会产生影响
- 另外的类想访问包里面的类:(同目录下的类不用import导入包)
- 写全名
- import引入包里面的类
- * : 如 com.bjsxt.java140.*;
- 全名: 如com.bjsxt.java140.Cat;
- 必须class文件的最上层包的父目录位于classpath下
实例:
Dog.java和com包在同一目录情况:
1、把Cat的.Class文件类放到包 com.bjsxt.java140 里面
2、Dog.class放在跟com包同目录下:
3、Cat.java程序代码:
package com.bjsxt.java140; public class Cat { }
4、Dog.java程序代码:
import com.bjsxt.java140.Cat; //写到Cat这个java文件名 //或者import com.bjsxt.java140.*; public class Dog { public static void main(String[] args) { //com.bjsxt.java140.Cat c = new com.bjsxt.java140.Cat(); 如果不导入包的话必须把名称写全!!! Cat C = new Cat(); } }
Dog.java和com包不在同一目录情况:
1、Dog.class文件位于com包的上一个目录
此时执行程序不能找到Cat.class文件,需要在CLASSPATH中配置路径才能使用包中的Cat.class
Cat.java程序代码:
package com.bjsxt.java140; public class Cat { }
Dog.java程序代码:
import com.bjsxt.java140.Cat; public class Dog { public static void main(String[] args) { Cat C = new Cat(); } }
新问题:
多个项目同时配置了CLASSPATH,项目A里面可能有 com.bjsxt.java140.Cat 项目B里面也可能有 com.bjsxt.java140.Cat ,会产生冲突问题。需要不同的项目设置不同的CLASSPATH,暂时不研究
当Dog.java也放在某个包里面:
1、cat.java代码,手动将Cat.class放入com.bjsxt.java140目录下:
package com.bjsxt.java140; public class Cat { }
2、Dog.java代码:
package com.bjsxt.java139; import com.bjsxt.java140.Cat; public class Dog { public static void main(String[] args) { Cat C = new Cat(); } }
3、当cat.class文件在com.bjsxt.java140目录下,Dog.java文件在com同目录下时,DOS执行javac Dog.java是可编译的
再手动将Dog.class放入com.bjsxt.java139目录下
4、此时DOS窗口切换到com上一级目录执行java Dog肯定是找不到Dog.class文件的,需要在执行java Dog指令时加入目录:
10、继承和权限控制
继承:
- Java使用extends关键字实现类的继承
- 通过继承,子类自动拥有父类的所有成员(成员变量和方法),即使是父类私有成员变量也会被继承下来,但是你只拥有私有变量的访问权(通过方法),没有使用权(直接调用)
- Java只支持单继承,不允许多继承
1 class Person { 2 private String name; 3 private int age; 4 public void setName(String name){ 5 this.name = name; 6 } 7 public String getName() { 8 return name; 9 } 10 public void setAge(int age) { 11 this.age = age; 12 } 13 public int getAge() { 14 return this.age; 15 } 16 } 17 18 class Student extends Person { 19 private String school; 20 public void setSchool(String school) { 21 this.school = school; 22 } 23 public String getSchool() { 24 return school; 25 } 26 } 27 28 public class Test { 29 public static void main(String[] args) { 30 Student stu = new Student(); 31 stu.setName("John"); 32 stu.setAge(18); 33 stu.setSchool("SCH"); 34 System.out.println(stu.getName()); 35 System.out.println(stu.getAge()); 36 System.out.println(stu.getSchool()); 37 } 38 }
访问控制:
成员变量:
类:
对于class的权限修饰只可以用public和default
- public类可以在任何地方被访问
- default类只可以被同一个包内部的类访问
11、方法的重写
- 在子类中可以根据需要对从父类中继承来的方法进行重写
- 重写方法必须和被重写方法具有相同的方法名称、参数列表和返回值
- 重写方法不能使用比被重写方法更严格的访问权限
重写的时候用ctrl+c、ctrl +v去拷贝,避免写错
12、super关键字
在java中使用super类引用父类的成分(this是当前对象的引用,super是当前对象里面那个父类对象的引用)
class T { public int value; public void f() { value = 100; System.out.println("T's value = " + value); } } class TT extends T{ public int value; public void f() { super.f(); //调用父类方法 value = 200; System.out.println("TT's value = " + value); System.out.println(value); System.out.println(super.value); } } public class Test { public static void main(String[] arts) { TT tt = new TT(); //刚初始化一个对象后,父类和子类value的值均被初始化为0.调用方法后才改变 tt.f(); } }
调用tt.f()后: 结果:
13、