1 package com.it.demo01_oop; 2 3 import java.util.Arrays; 4 5 /* 6 案例: 演示面向过程和面向对象代码的区别 7 8 面向过程编程思想详解: 9 面向过程思想其实就是一种编程思想. 所谓的面向过程开发, 指的就是面向着具体的每一个步骤和过程, 把每一个步骤和过程完成, 10 然后由这些功能方法相互调用, 完成需求. 11 12 记忆: 面向过程的代表语言是: C语言. 13 14 面向对象编程思想详解: 15 //推荐答题思路: 概述, 思想特点, 举例, 总结. 16 17 首先, 面向对象是一种编程思想, 它是基于面向过程的, 强调的是以 对象 为基础, 完成各种操作. 18 说道面向对象不得不提的就是它的3大思想特点: 19 1. 把复杂的事情简单化. 20 2. 更符合人们的思考习惯. 21 3. 把程序员从执行者变成指挥者. 22 举个例子吧, 买电脑, 洗衣服 (例子越契合当时的场景, 案例价值越高) 23 总结: 万物接对象. 24 25 程序开发: 26 就是在不断的创建对象, 使用对象, 指挥对象做事情. 27 28 程序设计: 29 就是在维护 对象 和 对象之间的关系. 30 */ 31 public class Demo01 { 32 public static void main(String[] args) { 33 //需求: 把数组元素按照[1, 2, 3, 4, 5]的格式进行输出. 34 35 //1. 定义数组, 记录元素. 36 int[] arr = {1, 2, 3, 4, 5}; 37 38 //2. 按照格式进行输出. 39 //方式一: 面向过程编程思想, 即: 每个动作都亲力亲为. 40 System.out.print("["); 41 for (int i = 0; i < arr.length; i++) { 42 if (i == arr.length - 1) 43 System.out.println(arr[i] + "]"); 44 else 45 System.out.print(arr[i] + ", "); 46 } 47 System.out.println("----------------------"); 48 49 50 //方式二: 面向对象编程思想, 即: 我们只要找对 对象即可, 把事儿交给他/她/它做. 51 System.out.println(Arrays.toString(arr)); 52 53 } 54 }
1 package com.it.demo01_oop; 2 3 import java.util.Scanner; 4 5 /* 6 案例: 演示学生类的定义和使用. 7 8 铺垫知识: 9 1. Java语言是用来描述现实世界事物, 最基本的单位是: 类. 10 2. 类就是 属性和行为 的集合, 是一个抽象的概念, 看不见, 也摸不着. 11 属性: 12 指的就是事物的外在特征(名词), 在Java中叫: 成员变量, 字段. 13 14 成员变量: 15 和以前定义变量的格式一样, 只不过写在类中方法外, 且成员变量有默认值. 16 17 行为: 18 指的就是事物能够做什么(动词), 在Java中叫: 成员方法 19 20 成员方法: 21 和以前定义方法格式一样, 只不过先不要写 static 22 3. 对象是类的具体体现, 实现, 能看的见, 也能摸得着. 23 4. 类的定义格式: 24 public class 类名 { 25 //属性 26 27 //行为 28 } 29 5. 类的调用格式, 即: 如何使用类中的成员 30 步骤1: 创建该类的对象. 31 类名 对象名 = new 类名(); 32 步骤2: 通过 对象名. 的形式调用类中的成员. 33 对象名.成员变量 //获取该成员变量的值. 34 对象名.成员变量 = 值 //获取指定成员变量的值. 35 对象名.成员方法() //调用指定的成员方法 36 37 */ 38 public class Demo02 { 39 public static void main(String[] args) { 40 //需求: 调用Student类中的成员. 41 //1. 创建学生类的对象. 42 Student s = new Student(); 43 44 //2. 打印属性值. 45 System.out.println(s.name); //null 46 System.out.println(s.age); //0 47 System.out.println("---------------------"); 48 49 //3. 设置属性值. 50 s.name = "刘亦菲"; 51 s.age = 33; 52 53 //4. 打印属性值. 54 System.out.println(s.name); //刘亦菲 55 System.out.println(s.age); //33 56 57 //5. 调用成员方法. 58 s.study(); 59 } 60 }
package cn.it.demo01; /* * 类的方式,描述现实中的事物 小汽车 * * 小汽车 属性和功能 * 属性: 颜色 轮胎个数 变量定义 * 功能: 跑 方法 * * 属性和方法,都属于类的成员 * * 属性, 成员变量 * 方法, 成员方法 */ public class Car { //定义Car类的属性 //定义颜色属性 String color ; //定义轮胎个数 int count ; //定义跑的功能 public void run(){ System.out.println("小汽车在跑 ..."+color+"..."+count); } } package cn.it.demo01; /* * 测试,自定义的类Car * 创建出Car类的变量 * 变量,调用属性,成员变量 * 变量,调用方法 */ public class CarTest { public static void main(String[] args) { //创建出Car类的变量 , 创建出Car类的对象,小汽车真的有了 Car c = new Car(); //对象.调用类中的属性和方法 c.color = "无色"; c.count = 5 ; c.run(); } }
1 package com.it.demo02_phone; 2 3 //自定义的手机类. 4 public class Phone { 5 //属性: 品牌(brand), 价格(price), 颜色(color) 6 String brand; //品牌 7 int price; //价格 8 String color; //颜色 9 10 // 行为: 打电话(call), 发短信(sendMessage) 11 public void call(String name) { 12 System.out.println("给" + name + "打电话!"); 13 } 14 15 //发短信(sendMessage) 16 public void sendMessage(String name) { 17 System.out.println("给" + name + "发短信!"); 18 } 19 20 } 21 22 package com.it.demo02_phone; 23 24 /* 25 案例: 演示手机类的定义和使用. 26 27 需求: 28 1.定义手机类Phone. 29 属性: 品牌(brand), 价格(price), 颜色(color) 30 行为: 打电话(call), 发短信(sendMessage) 31 2.创建测试类PhoneTest, 在类中定义main方法, 并访问手机类(Phone类)中的成员. 32 33 PhoneTest: 手机类的测试类.3 34 35 Phone: 具体的手机类. 36 */ 37 public class PhoneDemo { 38 public static void main(String[] args) { 39 //需求: 访问Phone类中的成员. 40 //1. 创建Phone类的对象. 41 Phone p = new Phone(); 42 //2. 打印属性值. 43 System.out.println(p.brand); 44 System.out.println(p.price); 45 System.out.println(p.color); 46 System.out.println("---------------------------"); 47 48 //3. 设置属性值. 49 p.brand = "华为P30"; 50 p.price = 5999; 51 p.color = "土豪金"; 52 53 //4. 打印属性值. 54 System.out.println(p.brand); 55 System.out.println(p.price); 56 System.out.println(p.color); 57 58 //5. 调用成员方法. 59 p.call("红红"); 60 p.sendMessage("红红"); 61 } 62 } 63 64 65 package com.it.demo02_phone; 66 67 //案例: 两个对象的内存图 68 public class PhoneDemo02 { 69 public static void main(String[] args) { 70 //1. 创建手机类的对象. 71 Phone p = new Phone(); 72 //2. 设置成员变量值. 73 p.brand = "华为"; 74 p.price = 6666; 75 p.color = "黑色"; 76 //3. 打印成员变量. 77 System.out.println(p.brand + "--" + p.price + "--" + p.color); 78 //4. 调用成员方法. 79 p.call("李四"); 80 p.sendMessage("李四"); 81 82 Phone p2 = new Phone(); 83 p2.brand = "小米"; 84 p2.price = 3333; 85 p2.color = "白色"; 86 System.out.println(p2.brand + "--" + p2.price + "--" + p2.color); 87 p2.call("张三"); 88 p2.sendMessage("张三"); 89 } 90 } 91 92 package com.it.demo02_phone; 93 94 //案例: 演示两个对象指向同一个地址的内存图. 95 public class PhoneDemo03 { 96 public static void main(String[] args) { 97 //1. 创建手机类的对象. 98 Phone p = new Phone(); 99 //2. 设置成员变量值. 100 p.brand = "华为"; 101 p.price = 6666; 102 p.color = "黑色"; 103 //3. 打印成员变量. 104 System.out.println(p.brand + "--" + p.price + "--" + p.color); //华为, 6666, 黑色 105 //4. 调用成员方法. 106 p.call("李四"); 107 p.sendMessage("李四"); 108 109 Phone p2 = p; 110 p2.brand = "小米"; 111 p2.price = 3333; 112 p2.color = "白色"; 113 System.out.println(p.brand + "--" + p.price + "--" + p.color); //小米, 3333, 白色 114 System.out.println(p2.brand + "--" + p2.price + "--" + p2.color); //小米, 3333, 白色 115 p2.call("张三"); 116 p2.sendMessage("张三"); 117 } 118 }
1 package com.it.demo03_variable; 2 3 /* 4 案例: 演示成员变量和局部变量的区别. 5 6 它们的区别有以下4点: 7 1. 定义位置不同. 8 成员变量: 定义在类中, 方法外的变量. 9 局部变量: 定义在方法中, 或者方法形参上的变量. 10 2. 在内存中存储位置不同. 11 成员变量: 存储在堆内存. 12 局部变量: 存储在栈内存. 13 3. 生命周期不同. 14 成员变量: 随着对象的创建而存在, 随着对象的消失而消失. 15 局部变量: 随着方法的调用而存在, 随着方法的调用完毕而消失. 16 4. 初始化值不同. 17 成员变量: 有默认值. 18 局部变量: 没有默认值, 必须先声明, 后赋值, 然后才能使用. 19 */ 20 public class Demo01 { 21 public static void main(String[] args) { 22 //需求: 调用Student#show(), 等价于: 调用Student类中的show()方法 23 //1. 创建Student类的对象. 24 Student s = new Student(); 25 //2. 调用指定的成员方法 26 s.show(); 27 } 28 } 29 30 31 package com.it.demo03_variable; 32 33 //自定义的学生类 34 public class Student { 35 //成员变量, 属性 36 int a = 20; 37 38 //成员方法, 行为 39 public void show() { 40 //局部变量 41 int b = 10; 42 43 System.out.println(a); //20 44 System.out.println(b); //10 45 } 46 }
1 package cn.it.demo02; 2 3 public class Car { 4 String color; 5 int count ; 6 public void run(){ 7 8 int x=1; 9 /*for(int i = 0 ; i < 4 ;i++){ 10 11 }*/ 12 System.out.println("小汽车在跑 ..."+color+"..."+count); 13 System.out.println(x); 14 } 15 } 16 17 18 19 package cn.it.demo02; 20 /* 21 * 成员变量和局部变量的区别 22 * 23 * 1. 定义位置上的区别 24 * 成员变量,定义在类中,方法外 25 * 局部变量,方法内,语句内 26 * 27 * 2. 作用域不同 28 * 成员变量,作用范围是整个类 29 * 局部变量,方法内,语句内 30 * 31 * 3. 默认值不同 32 * 成员变量,有自己的默认值 33 * 局部变量,没有默认值,不赋值不能使用 34 * 35 * 4. 内存位置不同 36 * 成员变量,跟随对象进入堆内存存储 37 * 局部变量,跟随自己的方法,进入栈内存 38 * 39 * 5. 生命周期不同 40 * 成员变量,跟随对象,在堆中存储,内存等待JVM清理 , 生命相对较长 41 * 局部变量,跟随方法,方法出栈 生命相对较短 42 */ 43 public class CarTest { 44 public static void main(String[] args) { 45 Car c = new Car(); 46 c.run(); 47 } 48 }
1 package cn.it.demo03; 2 3 public class Person { 4 String name ; 5 } 6 7 package cn.it.demo03; 8 /* 9 * 方法的参数类型,是基本数据类型,引用数据类型 10 */ 11 public class TestPerson { 12 public static void main(String[] args) { 13 int a = 1; 14 function(a); 15 System.out.println(a); 16 17 Person p = new Person(); 18 p.name = "张三"; 19 System.out.println(p.name); 20 21 function(p); 22 23 System.out.println(p.name); 24 } 25 /* 26 * 定义方法,参数类型是引用数据类型 27 * 参数是Person类型 28 * p接受的是一个内存的地址 29 * main 中的变量p 30 * function 中的变量p 保存的地址是一样的 31 */ 32 public static void function(Person p){ 33 p.name = "李四"; 34 } 35 36 /* 37 * 定义方法,参数类型是基本数据类型 38 */ 39 public static void function(int a){ 40 a+=5; 41 } 42 }
1 package com.it.demo04_private; 2 3 //自定义学生类 4 public class Student { 5 //属性 6 String name; 7 private int age; 8 9 //对外提供一个公共的访问方式, 来操作age变量. 10 //提供方法, 设置age的值. 11 public void setAge(int a) { 12 if (a >= 0 && a <= 250) { 13 //走到这里, 说明年龄合法. 14 age = a; 15 } 16 } 17 }package com.it.demo04_private; 18 19 /* 20 案例: 演示private关键字的用法. 21 22 private简介: 23 为什么要学习private? 24 因为目前我们代码中的成员变量, 外界是可以直接访问的, 这样的话, 用户就有可能给录入一些非法值, 25 造成安全隐患, 所以我们要对 成员变量进行一层封装, 不让外界直接访问了. 26 //大白话理解: 银行的钱用户是无法直接访问的, 要通过柜台小姐姐或者ATM自动存取款机来操作. 27 概述: 28 它是一个关键字, 表示"私有"的意思, 也是访问权限修饰符的一种, 29 被它修饰的内容, 只能在本类中直接使用. 30 31 应用场景: 32 1.在实际开发中, 成员变量基本上都是用private关键字来修饰的. 33 2.如果明确知道类中的某些内容不想被外界直接访问, 都可以通过private来修饰. 34 35 细节: 36 因为被private修饰的内容, 只能在本类中直接访问, 外界如果想使用这些私有成员, 需要通过特定方式. 37 即: 我们可以在类中定义两个方法, 一个是setXxx(), 用来设置属性值, 一个getXxx(), 用来获取属性值. 38 39 */ 40 public class StudentTest { 41 public static void main(String[] args) { 42 //1. 创建对象. 43 Student s = new Student(); 44 //2. 给属性赋值. 45 s.name = "刘亦菲"; 46 //s.age = -33; //私有成员外界无法直接访问. 47 s.setAge(33); 48 //3. 打印属性值. 49 System.out.println(s.name + "..." + s.getAge()); 50 //4. 调用成员方法. 51 s.study(); 52 } 53 }
package cn.it.demo04; /* * 描述现实生活中的人的事物 * 属性: 姓名 年龄 * 功能: 说话 * * 出现安全问题: age问题,可能出现赋值为负数的情况 * 负数不会导致程序问题,违反生活中的真实情况 * * 提高安全问题: 让外面的类,不允许直接调用我的成员变量 * 新的关键字 private 私有 属于成员修饰符,不能修饰局部变量 * 被private修饰的成员,只能在自己的本类中被使用 * * 对私有变量,提供公共的访问方式: 方法 */ public class Person { //人的姓名,成员变量 String name; //人的年龄,成员变量 private int age ; //变量age被私有,提供方法,让外面的类使用 //定义方法,对age变量进行赋值,方法名字,必须set开头 public void setAge(int a){ //对变量参数a进行范围的限制 if(a<0 || a > 200){ //如果a超过范围,手动将age赋值为20 age = 20; }else{ //如果a没有超过范围,直接对age赋值 age = a; } } //定义方法,对变量age获取值使用,方法名字get public int getAge(){ return age; } //定义人的说话功能,方法中,要求说出自己的姓名和年龄 public void speak(){ System.out.println(name+"..."+age); } } package cn.it.demo04; /* * 定义好的Person类进行测试 * 创建对象,对象调用属性和方法 */ public class PersonTest { public static void main(String[] args) { //创建Person类的对象 new Person p = new Person(); //对成员变量赋值 //p.age = -200; //对成员变量age赋值,只能调用Set方法赋值 p.setAge(50); p.name = "张三"; //调用类中方法 p.speak(); //输出成员变量age值,必须调用get方法 System.out.println(p.getAge()); } }
1 package com.it.demo05_student; 2 3 //自定义的学生类, 像这种用来描述实体的类也叫: 实体类, 或者JavaBean类, POJO类. 4 public class Student { 5 //属性: 姓名和年龄 6 private String name; //姓名 7 private int age; //年龄 8 9 //对外提供getXxx()和setXxx(), 让用户来操作name和age属性. 10 //获取姓名 11 public String getName() { 12 return name; 13 } 14 //设置姓名 15 public void setName(String n) { 16 //这里可以判断n(传入的姓名)是否合法, 但是我们不做 17 name = n; 18 } 19 20 //获取年龄 21 public int getAge(){ 22 return age; 23 } 24 25 //设置年龄 26 public void setAge(int a) { 27 //这里可以判断a(传入的年龄)是否合法, 但是我们不做 28 age = a; 29 } 30 31 //行为: 学习, 吃饭. 32 public void study() { 33 System.out.println("键盘敲烂, 月薪过万!"); 34 } 35 36 public void eat() { 37 System.out.println("学生吃牛肉!"); 38 } 39 } 40 41 package com.it.demo05_student; 42 43 /* 44 案例: 演示加入private关键字后的 "标准代码". 45 46 需求: 47 1.定义一个标准的学生类Student, 属性: 姓名和年龄, 行为: 学习, 吃饭. 48 2.在测试类中创建学生类的对象, 然后访问类中的成员. 49 50 StudentDemo类: 测试类. 51 */ 52 public class StudentDemo { 53 public static void main(String[] args) { 54 //1. 创建对象. 55 Student s = new Student(); 56 //2. 设置属性值. 57 //s.name = "刘亦菲"; //private修饰的内容, 外界无法直接访问. 58 s.setName("刘亦菲"); 59 /* 60 这里的-33是我们自己手动传入的, 实际开发中, 没有这种情况, 因为数据从前端传过来的, 61 当数据从前端传过来的时候, 已经经过了校验, 换言之, 我们在后台获取到的数据已经是合法的了, 62 如果再做校验属于二次校验, 可以做, 也可以不做, 一般不做, 具体看需求. 63 */ 64 //s.setAge(-33); 65 s.setAge(33); 66 //3. 打印属性值. 67 System.out.println(s.getName() + "..." + s.getAge()); 68 //4. 调用成员方法. 69 s.study(); 70 s.eat(); 71 } 72 }
package com.it.demo06_this; //自定义的学生类, 像这种用来描述实体的类也叫: 实体类, 或者JavaBean类, POJO类. public class Student { //属性: 姓名和年龄 private String name; //姓名 private int age; //年龄 //对外提供getXxx()和setXxx(), 让用户来操作name和age属性. //获取姓名 public String getName() { return name; } //设置姓名 public void setName(String name) { this.name = name; } //获取年龄 public int getAge(){ return age; } //设置年龄 public void setAge(int age) { this.age = age; } //行为: 学习, 吃饭. public void study() { System.out.println("键盘敲烂, 月薪过万!"); } public void eat() { System.out.println("学生吃牛肉!"); } } package com.it.demo06_this; /* 案例: 演示this关键字. 封装简介: 概述: 封装就是隐藏对象的属性和实现细节, 仅对外提供一个公共的访问方式. 怎么隐藏? 可以通过private关键字实现. 公共的访问方式是什么? getXxx(), setXxx() 原则: 1. 把不需要对外暴漏的内容都封装起来. 2. 把成员变量全部私有化(封装起来). //大白话翻译: 成员变量私有化(private修饰), 其他用public修饰. 好处: 1. 提高了代码的安全性. 由private保证. 2. 提高了代码的复用性. 由方法保证. this关键字简介 概述: 它是一个关键字, 代表本类当前对象的引用. //大白话: 谁调用, this就代表谁. 作用: 用来解决局部变量和成员变量重名问题的. 补充: 使用变量的原则 使用变量遵循就近原则, 如果局部位置有, 就使用, 没有就去本类的成员位置找, 有就是使用. 没有就报错. //先这么记忆, 不严谨, 因为本类找不到, 还回去父类找. */ public class StudentDemo { public static void main(String[] args) { //需求1: 调用Teacher#show(), 演示使用变量的原则. //method01(); //需求2: 加入this后的, 标准的Student类的代码编写和调用. //1. 创建对象. Student s = new Student(); //2. 设置属性值. //s.name = "刘亦菲"; //private修饰的内容, 外界无法直接访问. s.setName("刘亦菲"); s.setAge(33); //3. 打印属性值. System.out.println(s.getName() + "..." + s.getAge()); //4. 调用成员方法. s.study(); s.eat(); } public static void method01() { Teacher t = new Teacher(); t.a = 100; t.show(); } }
1 package cn.it.demo05; 2 3 /* 4 * 类描述人: 5 * 属性: 姓名和年龄 6 * 方法: 说话 7 * 8 * 私有化所有的属性 (成员变量) ,必须写对应的get/set方法 9 * 凡是自定义的类,自定义成员变量,应该私有化,提供get/set 10 * 11 * this关键字: 12 * 区分成员变量和局部变量同名情况 13 * 方法中,方位成员变量,写this. 14 */ 15 public class Person { 16 private String name; 17 private int age; 18 19 // set方法,变量name,age赋值 20 public void setAge(int age) { 21 this.age = age; 22 } 23 24 public void setName(String name) { 25 this.name = name; 26 } 27 28 // get方法,变量name,age获取值 29 public int getAge() { 30 return age; 31 } 32 33 public String getName() { 34 return name; 35 } 36 37 public void speak() { 38 String name = "哈哈"; 39 int age = 16; 40 41 System.out.println("人在说话 " + this.name + "..." + this.age); 42 } 43 } 44 45 46 package cn.it.demo05; 47 48 public class PersonTest { 49 public static void main(String[] args) { 50 Person p = new Person(); 51 //调用set方法,对成员变量赋值 52 p.setAge(18); 53 p.setName("旺财"); 54 p.speak(); 55 56 57 //调用get方法,获取成员变量的值 58 // System.out.println(p.getName()); 59 // System.out.println(p.getAge()); 60 } 61 }
package cn.it.demo06; public class Person { private int age; public void setAge(int age){ this.age = age; } public int getAge(){ return age; } /* * 定义方法: 比较是否是同龄人,是就返回true,不是就返回false * 谁和谁比呀,我自己和别人比 * 方法的返回值: true false * 方法参数: 别人 */ public boolean compare(Person p){ //自己和别人比年龄,自己是谁 this和p return this.age == p.age; } } package cn.it.demo06; public class PersonTest { public static void main(String[] args) { //测试Person类中的年龄比较功能 //创建出2个Person对象 Person p1 = new Person(); Person p2 = new Person(); p1.setAge(15); p2.setAge(16); //p1对象调用自己的方法compare传递p2对象 boolean b = p1.compare(p2); System.out.println(b); } }
1 package com.it.demo07_constructor; 2 3 //自定义的学生类 4 public class Student { 5 //属性 6 private String name; 7 private int age; 8 9 //系统默认加的空参. 10 public Student() { 11 System.out.println("我是空参构造方法"); 12 } 13 14 //自己给的全参 15 public Student(String name, int age) { 16 System.out.println("我是全参构造方法"); 17 this.name = name; 18 this.age = age; 19 } 20 } 21 22 package com.it.demo07_constructor; 23 24 /* 25 案例: 演示构造方法入门. 26 27 构造方法详解: 28 概述: 29 主职 兼职 30 构造方法就是用来快速创建对象的, 捎带着可以给对象的各个属性赋值. 31 注意事项: 32 1. 构造方法名和类名完全一致(包括大小写) 33 2. 构造方法没有返回值的数据类型, 连void都不能写. 34 3. 构造方法没有具体的返回值, 但是可以写return. 35 //return的作用是: 用来结束方法的, 捎带着可以返回具体的值. 36 4. 构造方法可以重载. 37 5. 每个类系统都会默认加一个: 空参构造, 如果你写了构造方法(不管是否是空参), 系统就不给了. 38 6. 推荐做法: 无论是否使用, 类中都要提供两个构造, 即: 空参构造, 全参构造. 39 格式: 40 public 类名(数据类型 参数名1, 数据类型 参数名2) { 41 //这里可以给该类中对应的成员变量赋值. 42 } 43 44 创建对象的格式: 45 类名 对象名 = new 构造方法名(值1, 值2, 值3); 46 */ 47 public class StudentDemo { 48 public static void main(String[] args) { 49 //创建Student类的对象 50 Student s = new Student(); 51 //s.setName("刘亦菲"); 52 //s.setAge(33); 53 System.out.println("----------------------"); 54 55 Student s2 = new Student("刘亦菲", 33); 56 } 57 }
1 package com.it.demo02_quickstart; 2 3 //自定义的人类, 表示父类. 4 public class Person { 5 //属性 6 private String name; //姓名 7 private int age; //年龄 8 9 //构造方法 10 public Person() { 11 } 12 13 public Person(String name, int age) { 14 this.name = name; 15 this.age = age; 16 } 17 18 //getXxx(), setXxx() 19 public String getName() { 20 return name; 21 } 22 23 public void setName(String name) { 24 this.name = name; 25 } 26 27 public int getAge() { 28 return age; 29 } 30 31 public void setAge(int age) { 32 this.age = age; 33 } 34 35 //行为 36 public void eat() { 37 System.out.println("人要吃饭!"); 38 } 39 40 public void sleep() { 41 System.out.println("人要睡觉!"); 42 } 43 44 public void smoking() { 45 System.out.println("人要抽烟!"); 46 } 47 } 48 49 50 package com.it.demo02_quickstart; 51 52 //自定义的学生类, 继承人类. 53 public class Student extends Person{ 54 //行为: 学习 55 public void study() { 56 System.out.println("学生要学习!"); 57 } 58 } 59 60 61 package com.it.demo02_quickstart; 62 63 //自定义的老师类, 继承人类. 64 public class Teacher extends Person{ 65 //构造方法, 子类的空参访问父类的空参, 子类的全参访问父类的全参. 66 67 //行为: 教课 68 public void teach() { 69 System.out.println("老师要教课!"); 70 } 71 }
package com.it.demo03_father; //自定义的爷爷类 public class GrandFather { public void grandFatherSay() { System.out.println("爷爷都是从孙子过来的"); } } package com.it.demo03_father; //自定义的爸爸类 public class Father extends GrandFather{ public void fatherSay() { System.out.println("爸爸都是从儿子过来的!"); } } package com.it.demo03_father; //自定义的儿子类. //public class Son extends Father, GrandFather{ //报错: Java中类与类之间只能单继承, 不能多继承. public class Son extends Father{ } package com.it.demo03_father; /* 案例: 演示Java中类与类之间的继承特点. 需求: 1.定义GrandFather类, 该类有一个grandFatherSay()方法, 该方法打印一句话爷爷都是从孙子过来的. 2.定义Father类, 该类有一个fatherSay()方法, 该方法打印一句话爸爸都是从儿子过来的. 3.定义Son类, 分别先继承自GrandFather类和Father类, 此时发现, 上述的两个方法只能同时调用一个. 4.如果想让Son类的对象, 同时能调用上述的两个方法, 则可以这样做: Son类继承自Father类, Father类继承自GrandFather类. 结论(记忆): Java中类与类之间的继承关系特点如下: 1. Java中类与类之间只能单继承, 不能多继承. //大白话翻译: 一个人只能有一个亲爹. 2. Java中支持多层继承. //大白话翻译: 一个人可以有一个亲爹, 还可以有一个亲爷爷. 3. 所有的类都直接或者间接继承自Object类, 换言之, Object类是所有类的父类. 快捷键: 查看继承关系树: ctrl + 字母H */ public class Demo01 { public static void main(String[] args) { Son s = new Son(); s.fatherSay(); //从Father类继承的. s.grandFatherSay(); //从GrandFather类继承的. } }
package cn.it.demo01; /* * 定义员工类 * 属性和方法 * 属性成员变量, 姓名 * 成员方法, 工作 */ public class Employee { String name; public void work(){ System.out.println("员工在工作"); } } package cn.it.demo01; /* * 定义研发部员工 * 属于员工中的一种 * 研发员工继承员工类 * * 关键字 extends * 子类是Develop, 父类是Employee * 子类自动拥有父类中可以继承的属性和方法 * * 子类中,可以直接调用父类的成员 */ public class Develop extends Employee{ //在子类中,可以定义方法 public void print(){ System.out.println(name); } } package cn.it.demo01; /* * 定义维护员工类 * 属于员工的一种, 继承员工类 */ public class WeiHu extends Employee{ public void print(){ System.out.println(name); } }
1 package com.it.demo03_variable; 2 3 //自定义的父类 4 public class Father { 5 //成员变量 6 int age = 30; 7 } 8 9 10 package com.it.demo03_variable; 11 12 //自定义的子类 13 public class Son extends Father { 14 //成员变量 15 int age = 20; 16 17 //成员方法 18 public void show() { 19 //局部变量 20 int age = 10; 21 System.out.println(age); //10 22 System.out.println(this.age); //20 23 System.out.println(super.age); //30 24 } 25 } 26 27 package com.it.demo03_variable; 28 29 /* 30 案例: 演示继承关系中的成员变量的访问特点: 31 32 需求: 33 1.定义Father类, 在该类的成员位置定义变量: int age = 30; 34 2.定义Son类, 让它继承Father类, 并在该类的成员位置定义变量: int age = 20; 35 3.在测试类FatherTest的main方法中, 定义变量: int age = 10; 36 4.通过输出语句, 直接打印age变量的值, 并查看程序的运行结果. 37 38 结论(记忆): 39 1. 使用变量遵循就近原则, 局部位置有使用, 没有就去本类的成员位置找, 40 有就使用, 没有就去父类的成员位置找, 有就使用, 没有就报错. //这里不考虑父类的父类这种情况, 会会一直找, 直到找到Object类. 41 2. 本类的局部变量, 本类的成员变量, 父类的成员变量重名时, 如何解决? 42 本类的局部变量: 直接写. 43 本类的成员变量: this.成员变量名 44 父类的成员变量: super.成员变量名 45 46 47 从本案例开始, 我们来研究继承关系中的成员特点: 48 成员变量的特点: 49 1. 就近原则. 50 2. 解决重名. super, this 51 构造方法的特点: 52 53 成员方法的特点: 54 */ 55 public class Demo01 { 56 public static void main(String[] args) { 57 //需求: 调用Son#show() 58 Son s = new Son(); 59 s.show(); 60 } 61 }
package com.it.demo04_constructor; //自定义的父类 public class Father { public Father() { //super(); //Father类的父类, Object类的. System.out.println("Father类的 空参 构造"); } public Father(String name) { //super(); //Father类的父类, Object类的. System.out.println("Father类的 带参 构造"); } } package com.it.demo04_constructor; //自定义的子类 public class Son extends Father{ /*public Son() { //super("abc"); //用来初始化Father类的成员的 this("abc"); System.out.println("Son类的 空参 构造"); } //这行代码走完,意味着Son对象创建成功. public Son(String name) { // super(name); //用来初始化Father类的成员的 System.out.println("Son类的 带参 构造"); }*/ //实际开发写法: 子类的空参访问父类的空参, 子类的全参访问父类的全参. public Son() { super(); System.out.println("Son类的 空参 构造"); } public Son(String name) { super(name); System.out.println("Son类的 带参 构造"); } } package com.it.demo04_constructor; /* 案例: 演示继承关系中 构造方法的访问特点.. 需求: 1.定义父类Father, 并在空参构造中打印一句话: Father空参构造. 2.定义子类Son, 并在空参构造中打印一句话: Son空参构造. 3.在FatherTest测试类的main方法中, 创建Son类的对象, 并查看程序的执行结果. 4.分别修改Father类和Son类的代码, 添加带参构造, 并观察程序的执行结果. 结论(记忆:): 1. 子类的所有构造方法的第一行默认都有一个: super() 访问父类的空参构造. 问题一: 为什么这样设计? 用于子类对象访问父类数据前, 对父类数据进行初始化. //大白话: 子类对象一旦创建成功, 就能直接使用父类的成员了, 因为父类成员在子类成员之前就已经初始化了. 问题二: 为什么默认访问的是空参, 而不是带参? 因为所有的类都直接或者间接继承自Object类, Object类是所有类的父类. 它里边只有一个空参构造. 问题三: 父类没有空参构造怎么办? 方案一: 通过 super()访问父类的带参构造. 方案二: 通过 this()访问本类的其他构造. 2. 实际开发写法: 子类的空参访问父类的空参, 子类的全参访问父类的全参. */ public class Demo01 { public static void main(String[] args) { //需求: 创建Son类的对象. Son s = new Son(); System.out.println("---------"); Son s2 = new Son("abc"); } }
package com.it.demo05_method; //自定义的Father类 public class Father { public void method() { System.out.println("Father method()方法"); } public void show() { System.out.println("Father show()方法"); } } package com.it.demo05_method; //自定义的子类 public class Son extends Father{ public void method() { super.method(); //调用父类的method()方法 System.out.println("Son method()方法"); } /* public void show() { System.out.println("Son show()方法"); }*/ } package com.it.demo05_method; /* 案例: 演示继承关系中的成员方法访问特点. 需求: 1.定义Father类, 并在类中定义method()方法和show()方法. 2.定义Son类, 并在类中定义method()方法和show()方法. 3.在FatherTest测试类中, 创建Son类的对象, 并调用类中的成员方法. 4.注释子类中的method()方法或者show()方法, 并观察程序的执行结果. 结论(记忆): 调用成员方法时, 也遵循就近原则, 本类中有, 就直接调用, 本类中没有, 就去父类中查找, 有就使用, 没有就报错. */ public class Demo01 { public static void main(String[] args) { Son s = new Son(); s.show(); System.out.println("-----------"); s.method(); } }
package com.it.demo06_override; //自定义的手机类 public class Phone { public void call(String name) { System.out.println("给" + name + "打电话"); } public void show() { System.out.println("show方法"); } } package com.it.demo06_override; //自定义的新式手机类 public class NewPhone extends Phone{ @Override public void call(String name) { super.call(name); //调用Phone#call()方法 System.out.println("新式手机会播放彩铃..."); } @Override public void show() { //报错: 父类中私有的方法不能被重写 System.out.println("show方法"); } /*private void show() { //报错: 父类中私有的方法不能被重写 System.out.println("show方法"); }*/ } package com.it.demo06_override; //自定义的手机类 public class Phone { public void call(String name) { System.out.println("给" + name + "打电话"); } public void show() { System.out.println("show方法"); } } package com.it.demo06_override; /* 案例: 演示方法重写. 需求: 1.定义Phone类, 并在类中定义call(String name)方法. 2.定义NewPhone类, 继承Phone类, 然后重写call(String name)方法. 3.在PhoneTest测试类中, 分别创建两个类的对象, 然后调用call()方法, 观察程序执行结果. 方法重写简介: 概述: 子类中出现和父类一模一样的方法时, 称为方法重写, 方法重写要求子父类的方法的返回值类型也必须一致. 应用场景: 当子类需要沿袭父类的功能, 但是功能主体又有自己独有需求的时候, 就可以考虑使用方法重写来实现了. 注意事项: 1.子类重写父类方法时, 方法声明上要用@Override注解来修饰. 2.父类中私有的方法不能被重写. 3.子类重写父类方法时, 访问权限不能更低. 访问权限修饰符的访问级别, 从小到大分别是: private < 默认 < protected < public */ public class Demo01 { public static void main(String[] args) { //测试Phone#call() Phone p = new Phone(); p.call("刘亦菲"); System.out.println("-----------------"); //测试NewPhoenix#call()方法 NewPhone np = new NewPhone(); np.call("赵丽颖"); } }
package com.it.demo07_exercise_person; //自定义父类, 人类. public class Person { //属性, 姓名, 年龄 private String name; //赵丽颖" private int age; //31 //构造方法 public Person() { } public Person(String name, int age) { //"赵丽颖", 31 this.name = name; this.age = age; } //getXxxx(), setXxx() public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } //行为: 吃饭. public void eat() { System.out.println("人要吃饭!"); } } package com.it.demo07_exercise_person; //自定义的学生类, 继承人类 public class Student extends Person{ //构造方法: 空参访问空参, 全参访问全参. public Student() { } public Student(String name, int age) { //"赵丽颖", 31 super(name, age); //"赵丽颖", 31 } //行为 //定义学习的方法 public void study() { System.out.println("学生要好好学习"); } @Override public void eat() { System.out.println("学生吃牛肉!"); } } package com.it.demo07_exercise_person; //自定义的老师类 public class Teacher extends Person { //变量, 目前没有. //构造方法: 子类空参访问父类空参, 子类全参访问父类全参. public Teacher() { } public Teacher(String name, int age) { super(name, age); } //行为 // 定义teach()方法. public void teach() { System.out.println("老师要教课!"); } //重写Person#eat() @Override public void eat() { System.out.println("老师喝牛肉汤!"); } } package com.it.demo07_exercise_person; /* 案例: 继承版的人类案例. 需求: 1.已知老师类Teacher, 属性有姓名和年龄, 行为有teach() 2.已知学生类Student, 属性有姓名和年龄, 行为有study() 3.他们都要吃饭, 不同的是学生吃牛肉, 老师喝牛肉汤. 4.分析上述的需求, 并通过代码实现. 5.在PersonTest类的main方法中, 分别创建老师类和学生类的对象, 然后访问其成员. 分析: 1. 抽取父类 Person. 属性: 姓名, 年龄 行为: 吃饭eat() 2. 定义子类Teacher, 继承Person 行为: 定义teach()方法. 重写Person#eat() 3. 定义子类Student, 继承Person 行为: 定义study()方法. 重写Person#eat()方法. */ public class PersonTest { public static void main(String[] args) { //需求: 测试学生类. //测试空参 Student s1 = new Student(); //学生是学生 //这些常用都是从Person类中继承过来的. s1.setName("刘亦菲"); s1.setAge(33); System.out.println(s1.getName() + "..." + s1.getAge()); s1.eat(); //重写Person#eat()方法 s1.study(); //Student类的独有功能. System.out.println("-------------------------"); //测试全参 Student s2 = new Student("赵丽颖", 31); System.out.println(s2.getName() + "..." + s2.getAge()); s2.eat(); s2.study(); //需求: 测试老师类, 代码留给你写了. } }
package com.it.demo08_quickstart; //自定义的动物类 public class Animal { public void eat() { System.out.println("动物要吃饭!"); } } package com.it.demo08_quickstart; //自定义的猫类, 继承动物类 public class Cat extends Animal{ //重写Animal#eat() @Override public void eat() { System.out.println("猫吃鱼!..."); } } package com.it.demo08_quickstart; /* 案例: 演示多态入门. 需求: 1.定义动物类Animal, 并在类中定义一个成员方法: eat() 2.定义猫类Cat, 继承Animal类, 并重写eat()方法. 3.在AnimalTest测试类的main方法中, 通过多态的方式创建猫类对象. 4.通过猫类对象, 调用eat()方法. 多态简介: 概述: 指的是同一个对象(事物)在不同时刻表现出来的不同形态, 状态. //例如: 一杯水, 高温: 气态, 常温: 液态, 低温: 固态. 前提条件: 1. 要有继承关系. 2. 要有方法重写. 3. 要有父类引用指向子类对象. */ public class AnimalTest { public static void main(String[] args) { //1. 通过多态的方式创建猫类对象. Animal an = new Cat(); //猫是动物. Cat c = new Cat(); //猫是猫 //2. 调用eat()方法 an.eat(); System.out.println(".............."); c.eat(); } }
package com.it.demo09_person; //自定义的人类 public class Person { int age = 30; public void eat() { System.out.println("Person eat()"); } /* public static void sleep() { System.out.println("Person sleep()"); }*/ } package com.it.demo09_person; //自定义的学生类 public class Student extends Person { int age = 20; @Override public void eat() { System.out.println("Student eat()"); } //自己独有的成员方法 public void study() { System.out.println("学生要学习!"); } /*public static void sleep() { System.out.println("Student sleep()"); }*/ } package com.it.demo09_person; /* 案例: 演示多态中的成员访问特点. 需求: 1.定义一个人类Person. 属性为姓名和年龄, 行为是: eat()方法. 2.定义Student类, 继承自Person类, 定义age属性及重写eat()方法. 3.在PersonTest测试类的main方法中, 创建Student类的对象, 并打印其成员. 结论(记忆): 成员变量: 编译看左, 运行看左. 成员方法: 编译看左, 运行看右. 解释: 编译看左的意思是: 在程序的编译期间, 会看左边的数据类型有没有这个成员, 有则编译通过, 否则, 编译报错. 运行看左(右)的意思是: 在程序的运行期间, 具体用的是左(右)边数据类型中的成员. 简单记忆: 只有非静态方法是 编译看左, 运行看右, 其他(成员变量, 静态方法)都是编译和运行都看左, 原因是因为: 只有非静态方法有方法重写. 多态的好处和弊端: 好处: 提高代码的扩展性. 弊端: 父类引用不能访问子类的特有功能. */ public class Demo01 { public static void main(String[] args) { //需求: 演示多态中的成员访问特点. //1. 通过多态, 创建学生类的对象. //父类引用 指向 子类对象, 多态写法. Person p = new Student(); //2. 测试访问成员变量 System.out.println(p.age); //30 //3. 测试访问成员方法 p.eat(); //student eat() //p.sleep(); //这样写会报错, 因为多态的弊端是: 父类引用不能访问子类的特有功能 //p.study(); } }
package com.it.demo10_case; //自定义的父类, 动物类 public class Animal { public void eat() { System.out.println("动物要吃!"); } } package com.it.demo10_case; //自定义的猫类 public class Cat extends Animal{ @Override public void eat() { System.out.println("猫吃鱼"); } //猫独有的成员方法 public void catchMouse() { System.out.println("猫会抓老鼠!"); } } package com.it.demo10_case; //自定义的父类, 动物类 public class Animal { public void eat() { System.out.println("动物要吃!"); } }
package com.it.demo11_animal; //父类, 动物类 public class Animal { //属性, 全部私有 private String name; private int age; //构造方法: 空参, 全参 public Animal() { } public Animal(String name, int age) { this.name = name; this.age = age; } //getXxx(), setXxx() public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } //行为 public void eat() { System.out.println("动物要吃!"); } } package com.it.demo11_animal; //猫类 public class Cat extends Animal{ //构造方法: 空参访问空参, 全参访问全参. public Cat() { } public Cat(String name, int age) { super(name, age); } //行为 //1. 重写Animal#eat() @Override public void eat() { System.out.println("猫吃鱼"); } //2. 自身独有的方法catchMouse() public void catchMouse() { System.out.println("猫会抓老鼠!"); } } package com.it.demo11_animal; //狗类 public class Dog extends Animal{ //构造方法: 空参访问空参, 全参访问全参. public Dog() { } public Dog(String name, int age) { super(name, age); } //行为 //1. 重写Animal#eat() @Override public void eat() { System.out.println("狗吃肉"); } //2. 自身独有的方法lookHome() public void lookHome() { System.out.println("狗会看家!"); } } package com.it.demo11_animal; import java.util.Calendar; /* 多态案例: 动物类案例. 需求: 1.已知猫狗都有姓名和年龄, 都要吃饭. 2.猫类独有自己的catchMouse()方法, 狗类独有自己的lookHome()方法. 3.在AnimalTest测试类的main方法中, 通过多态分别创建猫类, 狗类的对象. 4.分别通过猫类对象和狗类对象, 访问对象的成员. 分析: 父类: 动物类 Animal 属性: 姓名, 年龄 行为: eat()吃饭 子类: 猫类: Cat 行为: 1. 重写Animal#eat() 2. 自身独有的方法catchMouse() 狗类: Dog 行为: 1. 重写Animal#eat() 2. 自身独有的方法lookHome() */ public class AnimalTest { public static void main(String[] args) { //需求1: 多态测试猫类 //测试空参 Animal an1 = new Cat(); //设置成员变量值 an1.setName("机器猫"); an1.setAge(16); //打印成员变量值 System.out.println(an1.getName() + "..." + an1.getAge()); //调用方法 an1.eat(); //猫吃鱼, 因为有方法重写. //an1.catchMouse(); //报错, 父类应用不能直接使用子类的特有成员. Cat c1 = (Cat)an1; c1.catchMouse(); System.out.println("-------------------------"); //测试全参 Animal an2 = new Cat("加菲猫", 13); //打印成员变量值 System.out.println(an2.getName() + "..." + an2.getAge()); //调用方法 an2.eat(); //猫吃鱼, 因为有方法重写. //an2.catchMouse(); //报错, 父类应用不能直接使用子类的特有成员. Cat c2 = (Cat)an2; c2.catchMouse(); //需求2: 多态测试狗类, 自己写. //测试空参 //测试全参 } } package com.it.demo11_animal; /* 案例: 演示类型转换异常(ClassCastException) 大白话理解: 猫不能转成狗. */ public class AnimalTest02 { public static void main(String[] args) { Animal an = new Cat(); //动物是猫 Cat c = (Cat)an; //猫是猫 c.catchMouse(); System.out.println("-----------------"); //会报: 类型转换异常(ClassCastException) //多态 an = new Dog(); Dog d = (Dog)an; d.lookHome(); } } package com.it.demo11_animal; /* 案例: 演示多态在实际开发中的应用场景. 多态在实际开发中的应用场景: 父类型可以作为方法的形参类型, 这样可以接受其任意的子类对象, 然后调用方法的时候, 根据"编译看左, 运行看右"的原则, 传入什么 子类对象, 就调用其对应的方法. */ public class AnimalTest03 { public static void main(String[] args) { //测试: 调用猫类 Cat c = new Cat(); printAnimal(c); System.out.println("-------------"); //测试: 调用狗类 Dog d = new Dog(); printAnimal(d); } //需求: 定义方法, 接收动物类型的对象, 然后调用其eat()方法 //方式二: 采用多态解决. public static void printAnimal(Animal an) { //Animal an = ? an.eat(); } //方式一: Low版本, 一种动物, 一个方法. //针对于Cat(猫)类 public static void printAnimal(Cat c) { c.eat(); } //针对于Dog(狗)类 public static void printAnimal(Dog d) { d.eat(); } } package com.it.demo11_animal; /* 案例: 演示instanceof关键字的用法 instanceof关键字详解: 格式: 对象名 instanceof 数据类型(类名) 作用: 判断前边的对象, 是否是后边的数据类型, true: 是, false: 不是 */ public class AnimalTest04 { public static void main(String[] args) { //测试: 调用猫类 Cat c = new Cat(); printAnimal(c); System.out.println("-------------"); //测试: 调用狗类 Dog d = new Dog(); printAnimal(d); } //需求: 定义方法, 接收动物类型的对象, 然后调用其eat()方法 //方式二: 采用多态解决. public static void printAnimal(Animal an) { //Animal an = ? //通用功能 an.eat(); //某些子类独有的功能 if (an instanceof Cat) { Cat c = (Cat)an; c.catchMouse(); } else if (an instanceof Dog) { Dog d = (Dog)an; d.lookHome(); } } /* //方式一: Low版本, 一种动物, 一个方法. //针对于Cat(猫)类 public static void printAnimal(Cat c) { c.eat(); c.catchMouse(); } //针对于Dog(狗)类 public static void printAnimal(Dog d) { d.eat(); d.lookHome(); }*/ }
package com.it.demo01_final; //父类 //public final class Father extends Object{ //final修饰的类: 不能被继承, 但是可以继承其他类. public class Father{ int a = 10; public final void show() { System.out.println("这个是绝密文件, 不能动!"); } } package com.it.demo01_final; //子类 public class Son extends Father{ final int age = 20; //重写父类的show()方法, 这样写会报错, 因为父类用final修饰的方法, 子类无法重写. /*@Override public void show() { System.out.println("这个是垃圾文件, 赶紧删除!"); }*/ } package com.it.demo01_final; /* 案例: 演示final关键字 需求: 1.定义Father类, 并定义它的子类Son. 2.先用final修饰Father类, 看Son类是否还能继承Father类. 3.在Son类中定义成员变量age, 并用final修饰, 然后尝试给其重新赋值, 并观察结果. 4.在Father类中定义show()方法, 然后用final修饰, 看Son类是否能重写该方法. final关键字简介: 概述: 它是一个关键字, 表示 最终 的意思, 可以修饰类, 成员变量, 成员方法. 特点: //记忆 修饰的类: 不能被继承, 但是可以继承其他类. 修饰的变量: 是一个常量, 只能赋值一次. 修饰的成员方法: 不能被子类重写. */ public class FatherTest { public static void main(String[] args) { //演示final修饰局部变量. final int a = 10; //a = 20; //报错, final修饰的变量: 是一个常量, 只能赋值一次. System.out.println(a); System.out.println("------------------"); //演示final修饰成员变量. Son s = new Son(); //s.age = 30; 报错, final修饰的变量: 是一个常量, 只能赋值一次. System.out.println(s.age); System.out.println("------------------"); s.show(); } } package com.it.demo01_final; /* 案例: 演示final修饰的变量的特点. 结论(记忆): 1. final修饰的变量如果是基本类型: 说明值不能变化. 2. final修饰的变量如果是引用类型: 说明地址值不能变化, 但是属性值可以变化. */ public class FatherTest02 { public static void main(String[] args) { //演示: final修饰的变量如果是基本类型: 说明值不能变化. final int a = 10; //a = 20; //报错: final修饰的变量如果是基本类型: 说明值不能变化. //演示: final修饰的变量如果是引用类型: 说明地址值不能变化, 但是属性值可以变化. final Father f = new Father(); //f = new Father(); //报错, 说明地址值不能变化 f.a = 100; //不报错, 但是属性值可以变化 System.out.println(f.a); } }
package com.it.demo02_static; //学生类 public class Student { String name; //姓名 int age; //年龄 static String graduateFrom; //毕业院校, 共享 public Student() { } public Student(String name, int age) { this.name = name; this.age = age; } public Student(String name, int age, String graduateFrom) { this.name = name; this.age = age; this.graduateFrom = graduateFrom; } //定义show()方法, 用来打印上述的各个属性信息. public String show() { return name + "..." + age + "..." + graduateFrom; } } package com.it.demo02_static; /* 案例: 演示static关键字的特点 需求: 1.定义学生类, 属性为姓名, 年龄, 毕业院校(graduateFrom). 2.在学生类中定义show()方法, 用来打印上述的各个属性信息. 3.在测试类的main方法中, 创建学生对象, 并调用学生类的各个成员. static简介: 概述: 它是一个关键字, 表示 静态 的意思, 可以修饰成员变量, 成员方法. 特点: 1. 静态成员是随着类的加载而加载的. 2. 静态成员是优先于对象存在的. 3. 静态成员可以被该类下所有的对象所共享. //这个判断是否使用静态的一个标准. 4. 静态成员可以被 类名. 的形式调用, 也可以通过 对象名. 的形式调用, 推荐使用前者. */ public class StudentTest { public static void main(String[] args) { //前提: 这些学生都是同一个大学的学生. //学生来自于: 传智大学 Student.graduateFrom = "传智大学"; //创建学生, 属性值为: 刘亦菲, 33, 北影, 打印该学生的信息. Student s1 = new Student("刘亦菲", 33); System.out.println(s1.show()); //创建学生, 属性值为: 赵丽颖, 31, 北影, 打印该学生的信息. Student s2 = new Student("赵丽颖", 31, "北影"); System.out.println(s2.show()); //创建学生, 属性值为: 高圆圆, 35, 北影, 打印该学生的信息. Student s3 = new Student("高圆圆", 35); System.out.println(s3.show()); } }
package com.it.demo03_static; //学生类 public class Student { //属性 String name; //姓名, 非静态成员变量 static int age; //年龄, 静态成员变量 //行为 public void show1() { System.out.println(name); //非静态成员变量 System.out.println(age); //静态成员变量 show2(); //非静态方法 show4(); //静态方法 System.out.println("非静态 show1()方法"); } public void show2() { System.out.println("非静态 show2方法"); } public static void show3() { //System.out.println(name); //非静态成员变量 System.out.println(age); //静态成员变量 //show2(); //非静态方法 show4(); //静态方法 System.out.println("静态 show3()方法"); } public static void show4() { System.out.println("静态 show4()方法"); } } package com.it.demo03_static; /* 案例: 演示static的访问特点和注意事项. 需求: 1.定义学生类, 属性为姓名和年龄(静态修饰), 非静态方法show1(),show2(), 静态方法show3(), show4(). 2.尝试在show1()方法中, 调用: 姓名, 年龄, show2(), show4(). 结论: 非静态方法可以访问所有成员(非静态变量和方法, 静态变量和方法) 3.尝试在show3()方法中, 调用: 姓名, 年龄, show2(), show4(). 结论: 静态方法只能访问静态成员. 结论(记忆): 1. 静态成员方法只能访问静态成员(静态成员变量和静态成员方法). 大白话理解: 静态只能访问静态. 2. 在静态方法中, 是没有this, super关键字的. 3.因为静态的内容是随着类的加载而加载, 而this和super是随着对象的创建而存在. 即: 先进内存的, 不能访问后进内存的. */ public class StudentTest { public static void main(String[] args) { //需求: 调用Student#show1() Student s = new Student(); s.show1(); //非静态成员方法, 可以访问非静态成员, 也可以访问静态成员. System.out.println("---------------------"); //需求: 调用Student#show3(); Student.show3(); } }
package com.it.demo04_abstract; /* 案例: 抽象类入门. 结论(记忆): 1. 没有方法体的方法叫; 抽象方法. 2. 有抽象方法的类一定是抽象类. 3. 抽象方法和抽象类都用关键字: abstract修饰. */ public abstract class Animal { //抽象方法 public abstract void eat(); //非抽象方法 /*public void eat() { System.out.println("动物会吃!"); }*/ } package com.it.demo04_abstract; //测试类 public class AnimalTest { public static void main(String[] args) { //需求: 调用Animal#eat()方法 //下边这个代码是无意义的, 并没有给出具体的动物. //报错原因: 抽象类不能直接实例化. //Animal an = new Animal(); //动物是动物 //an.eat(); //动物会吃! } }
package com.it.demo05_animal; //父类, 动物类. public abstract class Animal { //抽象方法, 吃饭 public abstract void eat(); //非抽象方法, 睡觉. public void sleep() { System.out.println("动物要睡觉!"); } } package com.it.demo05_animal; //非抽象的子类, 猫类 public class Cat extends Animal{ //如果是普通类: 则必须重写父抽象类中 所有的抽象方法. @Override public void eat() { System.out.println("猫吃鱼"); } } package com.it.demo05_animal; //抽象的子类, 狗类 //抽象类的子类: 如果是抽象类, 则可以不用重写父抽象类中的 抽象方法. public abstract class Dog extends Animal{ } package com.it.demo05_animal; /* 案例: 演示抽象类的特点 需求: 1.定义抽象类Animal , 类中有一个抽象方法eat(), 还有一个非抽象方法sleep(). 2.尝试在测试类中, 创建Animal类的对象, 并观察结果. 3.创建普通类Cat, 继承Animal类, 观察是否需要重写Animal#eat()方法. 4.创建抽象类Dog, 继承Animal类, 观察是否需要重写Animal#eat()方法. 结论(记忆:): 1. 抽象方法和抽象类都要用 abstract 关键字修饰. 2. 有抽象方法的类一定是抽象类, 但是抽象类中不一定有抽象方法. 3. 抽象类不能直接实例化. 那抽象类如何实例化呢? 可以通过 多态的形式创建其子类对象, 来完成抽象类的初始化, 这种做法叫: 抽象类多态. 4. 抽象类的子类: 如果是普通类: 则必须重写父抽象类中 所有的抽象方法. 如果是抽象类: 则可以不用重写父抽象类中的 抽象方法. */ public class AnimalTest { public static void main(String[] args) { //Animal an = new Animal(); //报错, 抽象类不能直接实例化 //那抽象类如何实例化呢? //抽象类多态 Animal an = new Cat(); an.eat(); } }
package com.it.demo06_abstract; //人类, 抽象类 public abstract class Person { //变量 int age; //常量, 系统不给默认值, 留给用户来设置. final String country = "中国"; //null //构造方法 public Person() { } public Person(int age) { this.age = age; } //非抽象方法 public void eat() { System.out.println("人要吃饭!"); } //抽象方法 public abstract void sleep(); } package com.it.demo06_abstract; /* 需求: 演示抽象类的成员特点, 即抽象类中可以写什么. 需求: 1.定义抽象类Person, 在类中定义变量age, 常量country, 空参, 全参构造. 2.在Person类中定义非抽象方法show(), 抽象方法eat(). 3.在测试类的main方法中, 创建Person类的对象, 并调用类中的成员. 结论(记忆): 专业版: 抽象类中可以写变量, 常量, 构造方法, 非抽象方法, 抽象方法. 大白话版: 抽象类比普通类多一种抽象方法, 而且抽象方法还可以不写. */ public class PersonTest { public static void main(String[] args) { } }
package com.it.demo08_interface; /* 案例: 演示接口的成员特点, 即: 接口中可以写什么. 结论: 1. JDK1.8以前, 接口中有且只能有 常量 和 抽象方法, 原因是因为: 接口中的成员变量有默认修饰符: public static final 接口中的成员方法有默认就是福: public abstract 2. JDK1.8开始, 接口中可以写如下成员: 静态方法: 直接写即可, 和以前的规则一样. 默认方法: 即非静态方法, 要用 default 关键字修饰. */ public interface Inner { //接口中的成员变量有默认修饰符: public static final public static final int age = 20; //接口中的成员方法有默认就是福: public abstract //public abstract void eat(); //上述代码可以简写成: 如下的形式 void eat(); public static void show() { System.out.println("JDK1.8开始, 接口中可以写 静态方法了"); } public default void method() { System.out.println("JDK1.8开始, 接口中可以写 非静态(默认)方法了"); } } package com.it.demo08_interface; //测试类 public class InnerTest { public static void main(String[] args) { //调用接口中的 成员变量, 其实是一个常量 //Inner.age = 30; //报错, 常量值只能赋值一次, 不能修改. System.out.println(Inner.age); //调用接口中的 成员方法 Inner.show(); //下述代码会报错, 因为method()是默认方法(非静态), 必须通过 对象名. 的形式调用. //Inner.method(); } } package com.it.demo08_interface; //自定义接口Jumpping, 表示具有跳高功能. public interface Jumpping { //jump()方法, 表示具有跳高功能 public abstract void jump(); } package com.it.demo08_interface; /* 案例: 演示接口的特点. 需求: 1.定义Jumpping接口, 接口中有一个抽象方法jump(). 2.定义Cat类, 实现Jumpping接口, 重写jump()方法. 3.在测试类的main方法中, 创建Jumpping接口对象, 并调用其jump()方法 结论(记忆): 1. 接口用 interface 关键字修饰. 2. 类和接口之间是实现关系, 用关键字 implements 来修饰. 3. 接口不能直接实例化. 那接口如何实例化呢? 可以通过多态的形式, 创建其子类对象, 来完成接口的实例化. 这种写法叫: 接口多态. 4. 接口的子类: 如果是普通类: 则必须重写父接口中 所有的抽象方法. 如果是抽象类: 则可以不用重写父接口中的 抽象方法. */ public class JumpTest { public static void main(String[] args) { //演示: 接口不能直接实例化 //Jumpping jm = new Jumpping(); //接口不能直接实例化 // 那接口如何实例化呢? Jumpping jm = new Cat(); //接口多态 } } package com.it.demo08_interface; //自定义的猫类, 实现Jumpping接口 //接口的子类: 如果是抽象类, 则可以不用重写父接口中的 抽象方法. //public abstract class Cat implements Jumpping{ //接口的子类: 如果是普通类, 则必须重写父接口中 所有的抽象方法. public class Cat implements Jumpping{ @Override public void jump() { System.out.println("猫会跳高!"); } }
package com.it.demo09_interface_class; public class A { } package com.it.demo09_interface_class; public class B { } package com.it.demo09_interface_class; //演示: 类与类之间: 继承关系, 只能单继承, 不能多继承, 但是可以多层继承. //public class C extends B, A{ //报错 //演示: 类和接口之间: 实现关系, 可以单实现, 也可以多实现, 还可以在继承一个类的同时实现多个接口. //public class C implements Inner1{ //单实现 //public class C implements Inner1,Inner2{ //多实现 //public class C extends B implements Inner1,Inner2{ //继承一个类的同时实现多个接口. public class C implements Inner3{ @Override public void show3() { } @Override public void show1() { } @Override public void show2() { } }
package com.it.demo09_interface_class; public interface Inner1 { void show1(); } package com.it.demo09_interface_class; public interface Inner2 { void show1(); void show2(); } package com.it.demo09_interface_class; //演示: 接口与接口之间的关系: 继承关系, 可以单继承, 也可以多继承. public interface Inner3 extends Inner2, Inner1{ void show3(); }
package com.it.demo09_interface_class;
/*
案例: 演示接口 和 类之间的关系.
类与类之间:
继承关系, 只能单继承, 不能多继承, 但是可以多层继承.
类与接口直接:
实现关系, 可以单实现, 也可以多实现, 还可以在继承一个类的同时实现多个接口.
接口与接口之间:
继承关系, 可以单继承, 也可以多继承.
*/
public class Test {
}
package com.itheima.demo11_package; import java.util.Scanner; import java.util.HashSet; import java.io.InputStreamReader; /* 案例: 包的详解 包(package)的简介: 概述: 包就是文件夹, 用来区分重名类的, 多级包之间用.隔开, 一般是命名格式为: 公司域名反写 + 项目名 + 部门名(编号) + 功能模块 格式. 常见的分包方式: 基本划分: 一般是按照功能或者模块划分的 按照模块划分: com.itheima.student 学生模块 AddStudent DeleteStudent UpdateStudent SelectStudent com.itheima.teacher 老师模块 AddTeacher DeleteTeacher UpdateTeacher SelectTeacher 按照功能划分: com.itheima.add AddStudent AddTeacher ... com.itheima.delete DeleteTeacher DeleteStudent ... 高级划分: 按照具体的业务划分的 com.it.controller 控制层 com.it.service 业务层 com.it.dao 数据访问层 com.it.utils 存放的是所有的工具类 com.it.pojo 存放所有的JavaBean类 ... 格式: package 包名1.包名2.包名3; 注意事项: 1.package语句必须是程序的第一条可执行的代码. 2.package语句在一个.java文件中只能有一个. */ public class Demo01 { public static void main(String[] args) { } } //class A{ }
package com.it.demo10_exercise; //接口, 表示具有说英语的功能 public interface SpeakEnglish { void speakEnglish(); } package com.it.demo10_exercise; //父类, 人类 public abstract class Person { //属性: 姓名, 年龄 private String name; private int age; public Person() { } public Person(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } //行为: 吃 public abstract void eat(); } package com.it.demo10_exercise; //篮球教练类, 需要继承: 教练类 public class BasketballCoach extends Coach{ //构造方法, 子类空参访问父类空参, 子类全参访问父类全参. public BasketballCoach() { } public BasketballCoach(String name, int age) { super(name, age); } //重写吃的方法 @Override public void eat() { System.out.println("篮球教练吃羊肉, 喝牛奶"); } //重写教的方法 @Override public void teach() { System.out.println("篮球教练教如何运球和投篮"); } } package com.it.demo10_exercise; //教练类, 需要继承人类 public abstract class Coach extends Person{ //构造方法, 子类空参访问父类空参, 子类全参访问父类全参. public Coach() { } public Coach(String name, int age) { super(name, age); } //行为: 教学 public abstract void teach(); } package com.it.demo10_exercise; //运动员类, 需要继承人类 public abstract class Player extends Person{ //构造方法, 子类空参访问父类空参, 子类全参访问父类全参. public Player() { } public Player(String name, int age) { super(name, age); } //行为: 学习 public abstract void study(); } package com.it.demo10_exercise; //篮球运动员类, 需要继承: 运动员类 public class BasketballPlayer extends Player{ //构造方法, 子类空参访问父类空参, 子类全参访问父类全参. public BasketballPlayer() { } public BasketballPlayer(String name, int age) { super(name, age); } //重写学习的功能 @Override public void study() { System.out.println("篮球运动员学习如何运球和投篮"); } //重写吃饭的功能 @Override public void eat() { System.out.println("篮球运动员吃牛肉, 喝羊奶"); } } package com.it.demo10_exercise; //乒乓球运动员, 需要继承 运动员类, 还得实现 说英语的接口. public class PingPangPlayer extends Player implements SpeakEnglish{ //构造方法, 子类空参访问父类空参, 子类全参访问父类全参. public PingPangPlayer() { } public PingPangPlayer(String name, int age) { super(name, age); } //重写吃的功能 @Override public void eat() { System.out.println("乒乓球运动员吃大白菜, 喝小米粥"); } //重写学习的功能 @Override public void study() { System.out.println("乒乓球运动员学习如何发球"); } //重写说英语的功能 @Override public void speakEnglish() { System.out.println("乒乓球运动员需要学习如何 说英语"); } } package com.it.demo10_exercise; //篮球教练类, 需要继承: 教练类 public class BasketballCoach extends Coach{ //构造方法, 子类空参访问父类空参, 子类全参访问父类全参. public BasketballCoach() { } public BasketballCoach(String name, int age) { super(name, age); } //重写吃的方法 @Override public void eat() { System.out.println("篮球教练吃羊肉, 喝牛奶"); } //重写教的方法 @Override public void teach() { System.out.println("篮球教练教如何运球和投篮"); } } package com.it.demo10_exercise; //乒乓球教练, 需要继承 教练类, 还得实现 说英语的接口. public class PingPangCoach extends Coach implements SpeakEnglish{ //构造方法, 子类空参访问父类空参, 子类全参访问父类全参. public PingPangCoach() { } public PingPangCoach(String name, int age) { super(name, age); } //重写吃的方法 @Override public void eat() { System.out.println("乒乓球运动员吃小白菜, 喝大米粥"); } //重写教的方法 @Override public void teach() { System.out.println("乒乓球教练教如何发球"); } //重写说英语的方法 @Override public void speakEnglish() { System.out.println("乒乓球教练需要学习如何 说英语"); } }
package com.it; /* 案例: 演示各个权限修饰符的用法. 结论(记忆): 1. 测试图解 private 默认 protected public 本类中: √ √ √ √ 同包下的类(子类或者无关类均可): √ √ √ 不同包下的子类: √ √ 不同包下的无关类: √ 2. 四大访问权限修饰符的权限从小到大分别是: private < 默认 < protected < public 3. 大白话总结的结论(必须记忆): private: 强调的是给 本类 使用的. 默认: 强调的是给 同包下的类 使用的. protected: 强调的是给 子类 使用的. public: 强调的是给 大家 使用的. 以后写代码的时候, 如非必要, 基本都是: 成员变量全部用private修饰, 其他都用public修饰. */ public class Father { private void show1() { System.out.println("private show1()"); } void show2() { System.out.println("默认 show1()"); } protected void show3() { System.out.println("protected show1()"); } public void show4() { System.out.println("public show1()"); } public static void main(String[] args) { //创建Father类的对象, 调用四个方法 Father f = new Father(); f.show1(); f.show2(); f.show3(); f.show4(); } } package com.it; //测试四大访问权限修饰符, 该类和Father类的关系: 同包下的子类. public class Son extends Father { public static void main(String[] args) { //创建Father类的对象, 调用四个方法 Father f = new Father(); //f.show1(); private f.show2(); f.show3(); f.show4(); } }
package cn.it; //老师类 public class Teacher { public void method() { System.out.println("Teacher类的 method()方法"); } } package com.it; //学生类 public class Student { public void show() { System.out.println("Student类的 show()方法"); } } package com.it; /* 案例: 演示导包. 导包简介: 概述: 当我们使用不同包下的类的时候, 就需要导包. 如果是同包下的类, 可以直接使用. 格式: import 包名1.包名2.类名; //只导入一个具体的包, 推荐使用. import 包名1.包名2.*; //导入包2下所有的内容(包括所有的类和接口) */ public class Test { //main方法作为程序的主入口 public static void main(String[] args) { //需求1: 调用Student#show(), 同包下的类, 直接用, 无需导包. Student s = new Student(); s.show(); //需求2: 调用Teacher#method()方法, 不同包下的类的使用. //方式一: 写全类名(即: 包名 + 类名) cn.it.Teacher t1 = new cn.itcast.Teacher(); t1.method(); System.out.println("-------------------"); //方式二: 导包 Teacher t2 = new Teacher(); t2.method(); } } package com.it; //测试四大访问权限修饰符, 该类和Father类的关系: 同包下的无关类. public class Test02 { public static void main(String[] args) { //创建Father类的对象, 调用四个方法 Father f = new Father(); //f.show1(); private f.show2(); f.show3(); f.show4(); } }