● 对象与引用
引用数据类型:
是什么:除基本类型之外都称为引用类型
java中的对象是通过引用对其操作的
new Person()在堆内存空间中创建了一个对象
Person p1声明一个引用变量(所谓Person类的引用,就是以后可以用来指向Person )
对象的对象引用
"="把 对象内存空间的地址赋给了左边的引用变量
这样写,就比较清楚了,有两个实体:一是对象引用变量,一是对象本身
引用类型指的是用来执行对象的变量
/*
new Car(); 这个语句在堆空间里创建了实体,尽管它们也是确确实实存在的实体,但是我们看不见,也摸不着。
对象没有名字,也就没法直接访问它。我们需要通过对象引用来间接访问对象。
对象好比是一只很大的气球,但是我们抓不住它。引用变量是一根绳,可以用来系汽球。
Car car1; (1)创建一根绳子,一根还没有系上任何一个汽球的绳;
Car car2;(2)就又做了一根绳,还没系上汽球,
car1 = new Car();(3)给car1 系上气球;
car2 = car1 ;(4)这里,发生了复制行为。要说明的是,对象本身并没有被复制,被复制的只是对象引用。
结果是,car2也指向了car1所指向的对象。两根绳系的是同一只汽球。
*/
值传递与引用传递
Ep1:
/*
值传递 -- 基本类型作为参数
*/
public class TestValue {
public void test(int x){
x = 20;//变量x值发生变化,与a没有任何关系的 }
public static void main(String[] args) {
TestValue t = new TestValue();
int a = 10;
t.test(a);//传递的是基本类型,可是用a的值实际填充了x, 是两个不相干的变量
System.out.println(a);
}
}
10
Ep2:
/*
引用传递 (本质上也是值传递,只是为了和基本类型区分,称为引用地址传递)
*/
public class TestRef {
public void test(Person p){//p = p1 = 1001指向的是同一个对象
p.name = "李四"; }
public static void main(String[] args) {
TestRef t = new TestRef();
Person p1 = new Person(); //p1=1001
p1.name = "张三";
p1.age = 20;
t.test(p1);//对于引用类型,只是将对象的引用地址 值传递
System.out.println(p1.name);
}
}
李四
this关键字
this关键字代表当前对象 ,编译时区别成员变量,局部变量
使用this关键字引用成员变量
使用this关键字引用成员方法
this.成员变量名,用来区分同名的成员变量和局部变量。
Ep:
public class Person {
String name;
int age ;
public Person(){
}
public Person( String name,int age){
//this 表示正在调用的当前对象
this.name=name;
this.age=age;
}
public void show(){
System.out.println("姓名"+this.name+",年龄"+this.age);
}
}
public class TestPerson1 {
public static void main(String[] args) {
Person p1 =new Person("jim",20);
p1.show();
Person p2 =new Person("tom",20);
p2.show();
}
}
姓名jim,年龄20
姓名tom,年龄20
● static关键字
static 静态的 修饰类的属性,方法,代码块,内部类
修饰的内容和类一样只有一份
• 随着类的加载而加载
• 优先于对象存在
• 修饰的成员,被所有对象所共享
• 可不创建对象,直接被类调用
Ep1:
public class Chinese {
String name ;
/*
姓名 每个人姓名都不一样, 没创建一个对象,对象中就会有一个name属性
所有对象都一样的成员变量,可以修饰为static,称为类变量,随着类的加载而加载
*/
static String country="中国";
//国家, 每个对象中也都有一个country,就是一个静态变量 (类变量)
}
public class TestChinese {
public static void main(String[] args) {
/*
Chinese.name; name是非静态的成员变量,属于对象,类不能直接访问,
country被static修饰了,所有属于类,内存中只有一份,随着类加载而被加载初始化,建议使用类名访问静态
*/
System.out.println(Chinese.country); Chinese c1 = new Chinese();
System.out.println(c1.country);
//c1.country= "中国人";
Chinese.country = "中国人";
Chinese c2 = new Chinese();
System.out.println(c2.country);
}
}
中国
中国
中国人
Ep2:
public class Chinese {
String name ;
static String country="中国";
/*
static修饰的方法,也被称为类方法,通过类名访问,也是随着类的加载而加载.
静态方法里面不能访问非静态,因为静态的先加载,非静态的随着对象创建而加载(初始化)
*/
public static void showCountry(){
System.out.println("国籍:"+country);
}
public void showInfo(){
System.out.println("姓名"+name+"国籍"+country);
}
}
public class TestChinese {
public static void main(String[] args) {
/*
System.out.println(Chinese.country);
Chinese c1 = new Chinese();
System.out.println(c1.country);
Chinese.country = "中国人";
*/
Chinese c2 = new Chinese();
// System.out.println(c2.country);
c2.name = "jim";
c2.showInfo();
Chinese.showCountry();
}
}
姓名jim国籍中国人
国籍:中国人
● 代码块
代码块:在类中定义的代码,没有名字满足条件后会自动被调用
两种:
实例代码块:
(没有被static修饰的) 在创建对象时自动调用 ,实例代码块,先于 构造方法执行
静态代码块:
在类被加载时,只调用一次(默认认为一个类只被加载一次,一旦第一次加载后,就永远存在)
Ep:
public class Demo {
{
System.out.println("实例代码块1");
}
{
System.out.println("实例代码块2");
}
static {
System.out.println("静态代码块1");
}
static{
System.out.println("静态代码块2");
}
public Demo(){
System.out.println("无参构造");
}
public static void test(){
}
}
public class TestDemo {
public static void main(String[] args) {
//类只被加载一次: 类社什么时候会发生加载动作: 创 建对象,调用类中的静态成员
Demo.test();
new Demo(); //创建Demo类对象,先加载Demo类(加 载静态的成员)
new Demo();
}
}
静态代码块1
静态代码块2
实例代码块1
实例代码块2
无参构造
实例代码块1
实例代码块2
无参构造
类的加载执行
static >实例代码块 >构造方法
● 包
包-->可以理解为一个文件夹,组织管理类
是类的命名空间
类名 Car (类名的简称)
类名==全类名==包名(类的地址)+类名
包的命名:
字母一般都用小写;在包名中,可以使用.号来区分包的级别;
1)第一级 指该项目的类型
2)第二级 指项目所开发或者运行的公司名称
3)第三级 指项目的名称
4)第四级 指项目模块的名称
com.ffyc.javaoop.demo
1) com 项目类型 org 开源组织 gov 政府 edu教育类
2) ffyc 公司名称
3) javaoop 项目的名字
4) demo 按照不同的功能来管理命名
作用:
区分同名类
管理类(按照不同功能管理类)
访问权限控制
包可以更好得管理逻辑相关的类,可以控制不同包之间的访问权限
导入外部包的类,关键字"import"
Ep:
package com.ffyc.javaoop.test;
/*
import 导入其他包中的类 ,在一个类中需要用到另一个包中的类时,需要先导入 全类名
*/
import com.ffyc.javaoop.day2.Demo;
import java.util.Date;
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
new Demo();
new com.ffyc.javaoop.day3.Demo();
new Scanner(System.in);
//java.lang包下的类在使用时不需导入就可以使用
String s = "abc";
new Date();
new java.sql.Date(1000L);
/*
如果要调用两个不同包中类,但俩个类同名的情况下,第二个类要使用全类名调用
*/
}
}
● 访问权限修饰符
通过访问权限修饰符,对外是否可见
public 公共权限 修饰类、属性、方法。可以被任意类访问
public修饰类时,类名必须与文件名字一致
一个.java文件中,只能有一个public修饰的类
protected 受保护的权限 修饰属性、方法
可以被同包类访问,如果不是同包类,必须是该类的子类才可以访问。
(default) 同包权限 修饰类、属性、方法。只能被同包的类访问
private 私有权限 修饰属性、方法。 只能在本类中访问
Ep1:
package com.ffyc.javaoop.day2;
public class Demo {
public int pub; //公共权限 修饰类、属性、方法。
protected int pro; //受保护权限 修饰属性、方法。
int num; //默认权限 同包权限 修饰类、属性、方法。
private int pri; //私有权限 修饰属性、方法。 只能在本类中访问
public void putMethod(){
}
protected void proMethod(){
}
void method(){
}
private void priMethod(){
}
public static void main(String[] args) {
Demo demo = new Demo();
demo.pub = 10;
demo.pro = 20;
demo.num = 30;
demo.pri = 40;
}
}
Ep2:
package com.ffyc.javaoop.day3;
public class Demo {
public static void main(String[] args) {
com.ffyc.javaoop.day2.Demo demo = new com.ffyc.javaoop.day2.Demo();
demo.pub = 10;//公共权限 任意类
//demo.pro =20;受保护权限 同包不同类+异包子类
//demo.num =30; 默认权限 同包不同类
//demo.pri =40; 私有权限 只能在本类中访问使用
}
}
protected Ep:
package com.ffyc.javaoop.day3;
import com.ffyc.javaoop.day2.Demo;
//extends 表示继承另一个类
public class DemoChild extends Demo {
public static void main(String[] args) {
com.ffyc.javaoop.day2.Demo demo = new com.ffyc.javaoop.day2.Demo();
System.out.println(demo.pub);
DemoChild demoChild = new DemoChild();
demoChild.pro = 10;//使用不同包的子类访问受保护的权限修饰的成员
}
}
● 面向对象特征--封装
面向对象语言三大特征(封装,继承,多态)之一
封装: 一词多义
面向对象中的封装:指的是通过访问权限修饰符,使得类中的信息是否对外可见(隐藏类中的信息)
封装的概念:将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问 。
封装的好处:只能通过规定方法访问
方便修改实现
方便加入控制语句
隐藏类的实现细节
Ep:
public class Person {
/*
封装使用案例 使用private这个权限修饰符对成员变量进行修饰,在其他类中访问不到了
*/
private String name;
private int age;
private Person(){
}
public static Person createPerson(){
if(person==null){
person = new Person();
}
return person;
}
/*为封装起来的成员变量,提供一个特定的公共权限的方法,用来为其赋值,
方便我们自己加入一些控制语句
name属性赋值
*/
public void setName(String name){
if(name!=null||name.length()<10){
this.name = name;
}//加入控制语句
}
//获取name属性值
public String getName(){
return this.name;
}
public void setAge(int age){
this.age = age;
}
public int getAge(){
return this.age;
}
}
public class TestPerson {
public static void main(String[] args) {
/*
zs.name = "asfhjdsfgfdlbgjfdbgfdjigbhvgdsvfdsgyfv"; 在其他地方可以对Person中的name进行赋值
不好控制赋值操作
将name属性隐藏起来,
*/
Person zs = new Person();
zs.setName("zs");
Person zs1 = new Person();
zs1.setName("jim");
System.out.println(zs1.getName());
System.out.println(zs.getName());
}
}
jim
zs
设计模式(23种): 一系列解决问题方案 算法 单例设计模式 : 解决只让一个类在一个程序中创建一个唯一的对象
Ep:
package com.ffyc.javaoop.day2;
public class Person {
private static Person person=null;
private Person(){
}
public static Person createPerson(){
if(person==null){
person = new Person();
}
return person;
}
}
package com.ffyc.javaoop.day2;
public class TestPerson1 {
public static void main(String[] args) {
Person zs1 = Person.createPerson();
Person zs2 = Person.createPerson();
System.out.println(zs1);
System.out.println(zs2);
/*
zs1和zs2为同一对象;
*/
}
}
com.ffyc.javaoop.day2.Person@1b6d3586
com.ffyc.javaoop.day2.Person@1b6d3586