首页 文章 精选 留言 我的

精选列表

搜索[学习],共10000篇文章
优秀的个人博客,低调大师

java基础学习_面向对象(下)02_day09总结

==========================================================================================================================================================涉及的知识点有: 1:final关键字(掌握) 2:多态(掌握) 3:抽象类(掌握) 4:接口(掌握)==========================================================================================================================================================1:final关键字(掌握) (0)由于继承中方法有一个现象:方法重写。 所以,父类的功能,就会被子类给覆盖掉。 有些时候,我们不想让子类去覆盖掉父类的功能,只能调用但不能去覆盖修改。 这个时候,针对这种情况,Java就提供了一个关键字:final。--------------------------------------- (1)final是最终的意思,常见的final可以修饰类、方法、变量。 (2)fianl的特点: A:final修饰的类,不能被继承。 编译报错:无法从最终Fu进行继承 应用:最底层的那个类可以用final修饰,这样该类就不能有儿子了。(即绝育) B:final修饰的方法,不能被重写(覆盖/复写)。 编译报错:Zi中的show()无法覆盖Fu中的show() C:final修饰的变量,是一个常量,只能被赋值一次。 编译报错:无法为最终变量num2分配值 注意:被final修饰的成员变量没有默认值,必须在构造器(constructor )结束之前被赋予一个明确的值。即在定义被final修饰的成员变量时就给值。 小补充: 常量分为两种: 1.字面值常量 例如:"hello"、10、true 2.自定义常量 例如:final int x = 10;--------------------------------------- (3)final关键字面试题相关: public、private等权限修饰符会用来修饰成员变量、构造方法和成员方法。 不会用来修饰局部变量(在方法内部的变量),因为权限修饰符修饰局部变量是没有意义的,在方法内部的局部变量是被封装好的,外界的方法看不到。 final既可以修饰局部变量也可以修饰成员变量和成员方法。 A:final修饰局部变量 a:当局部变量为基本数据类型 值不能发生改变 final x = 100; b:当局部变量为引用数据类型 地址值不能发生改变,但是该对象的堆内存的内容是可以改变的。 final Student s = new Student(); s = new Student(); //对象s重新指向了新的地址值,但是对象s被final修饰了,所以这句会报错!--------------------------------------- B:final修的饰变量的初始化时机 a:被final修饰的变量只能被初始化一次(默认初始化不算哦)。 b:被final修饰的变量的初始化时机:在对象构造方法执行完毕前进行赋值就行。 注意:这个时机仅仅针对的是非静态的常量。因为静态的早早就加载了。 c:变量常见的给值时机 1.在定义的时候就给值。(推荐方式) 2.在构造代码块中给值。 3.在构造方法中给值。----------------------------------------------------------------------------- 2:多态(掌握) (1)某一个事物,在不同时刻表现出来的不同状态。 猫可以是猫的类型。 猫 m = new 猫(); 同时猫也是动物的一种,也可以把猫称为动物。 动物 d = new 猫(); 再举一个例子:水在不同时刻的状态。--------------------------------------- (2)多态的前提和体现: A:多态有继承或者实现关系。 B:多态有方法重写。(因为多态是靠方法重写来体现不同状态的) 其实没有方法重写也是可以的,但是如果没有方法重写就没有意义了。 C:多态有父类或者父接口引用指向子类对象。 即:父 f = new 子(); 多态的分类: a:具体类的多态 class Fu {} class Zi extends Fu {} Fu f = new Zi(); b:抽象类的多态 abstract class Fu {} class Zi extends Fu {} Fu f = new Zi(); c:接口的多态 interface Fu {} class Zi implements Fu {} Fu f = new Zi();--------------------------------------- (3)多态中的成员访问特点: A:对于多态中的成员变量的访问 编译看左边,运行看左边。 因为子可以访问父的成员变量,父不可以访问子的成员变量。(即:对于成员变量,可以向上访问,不可以向下访问。) B:对于多态中的构造方法的访问 创建子类对象的时候,子类的构造都会默认访问父类构造,为了对父类的数据进行初始化。 C:对于多态中的成员方法的访问 编译看左边,运行看右边。 因为成员方法有重写,父类的成员方法会被子类覆盖掉。因为成员方法是跟对象相关的。 D:对于多态中的静态方法的访问 编译看左边,运行看左边。 因为静态方法只能被静态方法重写,但是静态方法根本算不上重写。因为静态是跟类相关的。所以访问静态方法的时候是左边。 为什么? 因为成员方法有方法重写,父类的动作被子类重写掉了,所以该动作走的是儿子的。 也即对于多态中的成员方法的访问看右边(子类)。--------------------------------------- (4)多态的好处: A:提高了代码的维护性(继承体现) 因为多态有继承或者实现关系。 B:提高了代码的扩展性(多态体现) 原因如下: 猫狗案例: 注意几点: 测试类里面不能放其他东西,只能放创建的对象和通过对象调用的方法。 把构造方法私有,别人就不能创建对象了,只能通过类名来调用静态方法了。 针对动物操作的工具类中,调用动物的功能时,形参用动物类进行接收(即多态)。 即 Animal a = new Cat(); a = new Dog(); a = new Pig(); ......--------------------------------------- (5)多态的弊端: Fu f = new Zi(); 父类不能使用子类的特有功能(即成员方法)。 因为我们拿父类去访问子类,但是对于成员方法,父类只能访问在父类中定义的方法,在父类中没有定义的方法不能访问。 简言之:子可以当做父使用,父不能当做子使用。因为子比父的东西要多。 我父类就想使用子类的特有功能?行不行? 答:行。 那怎么行呢? 法一:创建子类对象调用方法即可。(可以,但是很多时候不合理。而且,重新创建对象,太占内存了。) Zi z = new Zi(); 法二:把父类的引用强制赋值给子类的引用。(向下转型)(这样做内存中只有一个对象,省内存!) 因为引用类型赋值要求类型要兼容! Zi z = (Zi)f;--------------------------------------- (6)多态中的转型问题: A:向上转型 从子到父 Fu f = new Zi(); B:向下转型 从父到子 Zi z = (Zi)f; //前提:要求该f必须是能够转换为Zi的。--------------------------------------- (7)孔子装爹的案例帮助大家理解多态 //然后就穿上爹的衣服,带上爹的眼睛,粘上爹的胡子。就开始装爹。 //其实就是向上转型。 孔子爹 k爹 = new 孔子(); //脱下爹的装备,换上自己的装备。 //其实就是向下转型。 孔子 k = (孔子)k爹; --------------------------------------- (8)多态的练习 A:猫狗案例 B:老师和学生案例-----------------------------------------------------------------------------3:抽象类(掌握) (1)抽象类的概述: 把多个共性的东西提取到一个类中,这是继承的做法。 但是呢,这多个共性的东西,在有些时候,方法声明是一样的,但是方法体不一样。 也就是说,方法声明是一样,但是每个具体的对象在具体实现的时候内容不一样。 所以,我们在定义这些共性的方法的时候,就不能给出具体的方法体。 在Java中,一个没有具体的方法体的方法应该定义为抽象方法。 而在一个类中如果有抽象方法,该类必须定义为抽象类。--------------------------------------- (2)抽象类的特点: A:抽象类和抽象方法必须用关键字abstract修饰。 格式: abstract class 类名 {} public abstract void eat(); //没有方法体。 //public abstract void eat() {} //有方法体,但方法体为空。会报错。 B:抽象类中不一定有抽象方法,但是有抽象方法的类一定是抽象类。 C:抽象类不能实例化。 例如: abstract class Animal {} Animal a = new Animal(); //会报错,因为动物类是抽象的,不能new。 抽象类有构造方法,但是不能实例化。 那么抽象类的构造方法的作用是什么呢? 答:用于子类访问父类数据初始化。 D:抽象类的子类可能是: a:抽象类的子类可以是一个抽象类。这个子类不用重写抽象类中的抽象方法。 b:抽象类的子类可以是一个具体类(可以new对象,使用多态实例化抽象类)。但这个子类必须重写抽象类中的所有抽象方法。 E:抽象类的实例化 通过具体的子类实现的(即:多态的方式。也即:向上转型的方式),其实这也是多态的一种,叫做抽象类多态。 多态最主要的应用是在抽象类中使用,而不是在具体类中。这样抽象类对外界提供的是抽象的方法,而靠真正具体的子类来重写实现的。--------------------------------------- (3)抽象类的成员特点: A:抽象类的成员变量的特点 可以有变量 也可以有常量 B:抽象类的构造方法的特点 有构造方法,但是不能实例化。用于子类访问父类数据的初始化。 C:抽象类的成员方法的特点 可以有抽象方法 强制具体的子类必须完成某些动作。 也可以有非抽象方法 使子类继承非抽象方法,提高代码复用性。--------------------------------------- (4)抽象类的练习: A:猫狗案例练习 示例代码如下: 1 /* 2 猫狗案例练习: 3 具体事物:猫,狗 4 共性:姓名,年龄,吃饭 5 --------------------------------------- 6 分析:从具体到抽象 7 猫类: 8 成员变量:姓名,年龄 9 构造方法:无参,带参 10 成员方法:吃饭(猫吃鱼) 11 12 狗类: 13 成员变量:姓名,年龄 14 构造方法:无参,带参 15 成员方法:吃饭(狗吃肉) 16 17 因为有共性的内容,所以就提取了一个父类。动物类。 18 但是又由于吃饭的内容不一样,所以吃饭的方法是抽象的, 19 而方法是抽象的,则类就必须定义为抽象类。得到抽象动物类。 20 21 抽象动物类: 22 成员变量:姓名,年龄 23 构造方法:无参,带参 24 成员方法:吃饭(); 25 --------------------------------------- 26 实现:从抽象到具体 27 抽象动物类: 28 成员变量:姓名,年龄 29 构造方法:无参,带参 30 成员方法:吃饭(); 31 32 具体的狗类: 33 继承自抽象动物类 34 重写吃饭(); 35 36 具体的猫类: 37 继承自抽象动物类 38 重写吃饭(); 39 40 测试类: 41 */ 42 43 //定义抽象的动物类 44 abstract class Animal { 45 //姓名 46 private String name; 47 //年龄 48 private int age; 49 50 public Animal() {} 51 52 public Animal(String name, int age) { 53 this.name = name; 54 this.age = age; 55 } 56 57 public String getName() { 58 return name; 59 } 60 61 public void setName(String name) { 62 this.name = name; 63 } 64 65 public int getAge() { 66 return age; 67 } 68 69 public void setAge(int age) { 70 this.age = age; 71 } 72 73 //定义一个抽象的方法 74 public abstract void eat(); 75 } 76 77 //定义具体的狗类 78 class Dog extends Animal { 79 public Dog() {} 80 81 public Dog(String name, int age) { 82 super(name, age); 83 } 84 85 public void eat() { 86 System.out.println("狗吃肉"); 87 } 88 } 89 90 //定义具体的猫类 91 class Cat extends Animal { 92 public Cat() {} 93 94 public Cat(String name, int age) { 95 super(name, age); 96 } 97 98 public void eat() { 99 System.out.println("猫吃鱼"); 100 } 101 } 102 103 //测试类 104 class AbstractTest { 105 public static void main(String[] args) { 106 //测试狗类 107 //具体类测试 108 //方式1: 109 Dog d = new Dog(); 110 d.setName("旺财"); 111 d.setAge(3); 112 System.out.println(d.getName()+"---"+d.getAge()); 113 d.eat(); 114 //方式2: 115 Dog d2 = new Dog("旺财", 3); 116 System.out.println(d2.getName()+"---"+d2.getAge()); 117 d2.eat(); 118 System.out.println("---------------------------"); 119 120 //多态测试:因为子类中没有定义特有功能,所以可以多态实现。 121 Animal a = new Dog(); 122 a.setName("旺财"); 123 a.setAge(3); 124 System.out.println(a.getName()+"---"+a.getAge()); 125 a.eat(); 126 127 Animal a2 = new Dog("旺财", 3); 128 System.out.println(a2.getName()+"---"+a2.getAge()); 129 a2.eat(); 130 System.out.println("---------------------------"); 131 132 //练习:测试猫类 133 //具体类测试 134 //方式一: 135 Cat c = new Cat(); 136 c.setName("多啦A梦"); 137 c.setAge(5); 138 System.out.println(c.getName()+"---"+c.getAge()); 139 c.eat(); 140 //方式二: 141 Cat c2 = new Cat("哆啦A梦", 5); 142 System.out.println(c2.getName()+"---"+c2.getAge()); 143 c2.eat(); 144 System.out.println("---------------------------"); 145 146 //多态测试:因为子类中没有定义特有功能,所以可以多态实现。 147 Animal a3 = new Cat(); 148 a3.setName("哆啦A梦"); 149 a3.setAge(5); 150 System.out.println(a3.getName()+"---"+a3.getAge()); 151 a3.eat(); 152 153 Animal a4 = new Cat("哆啦A梦", 5); 154 System.out.println(a4.getName()+"---"+a4.getAge()); 155 a4.eat(); 156 157 } 158 } B:老师案例练习 示例代码如下: 1 /* 2 老师案例练习: 3 具体事物:基础班老师,就业班老师 4 共性:姓名,年龄,讲课 5 --------------------------------------- 6 分析: 7 基础班老师类 8 姓名,年龄 9 无参,带参 10 讲课(讲解JavaSE) 11 就业班老师类 12 姓名,年龄 13 无参,带参 14 讲课(讲解JavaEE) 15 抽象老师类 16 姓名,年龄 17 无参,带参 18 讲课(); 19 --------------------------------------- 20 实现: 21 抽象老师类 22 具体的基础班老师类 23 具体的就业班老师类 24 测试类 25 */ 26 27 //定义抽象的老师类 28 abstract class Teacher { 29 //姓名 30 private String name; 31 //年龄 32 private int age; 33 34 public Teacher() {} 35 36 public Teacher(String name, int age) { 37 this.name = name; 38 this.age = age; 39 } 40 41 public String getName() { 42 return name; 43 } 44 45 public void setName(String name) { 46 this.name = name; 47 } 48 49 public int getAge() { 50 return age; 51 } 52 53 public void setAge(int age) { 54 this.age = age; 55 } 56 57 //抽象方法 58 public abstract void teach(); 59 } 60 61 //具体的基础班老师类 62 class BasicTeacher extends Teacher { 63 public BasicTeacher(){} 64 65 public BasicTeacher(String name, int age) { 66 super(name, age); 67 } 68 69 public void teach() { 70 System.out.println("基础班老师讲解JavaSE"); 71 } 72 } 73 74 //具体的就业班老师类 75 class WorkTeacher extends Teacher { 76 public WorkTeacher(){} 77 78 public WorkTeacher(String name, int age) { 79 super(name, age); 80 } 81 82 public void teach() { 83 System.out.println("就业班老师讲解JavaEE"); 84 } 85 } 86 87 class AbstractTest2 { 88 public static void main(String[] args) { 89 //具体的类测试,自己玩 90 //基础班老师 91 //方式一: 92 BasicTeacher bt = new BasicTeacher(); 93 bt.setName("刘意"); 94 bt.setAge(30); 95 System.out.println(bt.getName()+"---"+bt.getAge()); 96 bt.teach(); 97 //方式二: 98 bt = new BasicTeacher("刘意", 30); 99 System.out.println(bt.getName()+"---"+bt.getAge()); 100 bt.teach(); 101 System.out.println("--------------"); 102 103 //就业班老师 104 //方式一: 105 WorkTeacher wt = new WorkTeacher(); 106 wt.setName("林青霞"); 107 wt.setAge(27); 108 System.out.println(wt.getName()+"---"+wt.getAge()); 109 wt.teach(); 110 //方式二: 111 wt = new WorkTeacher("林青霞", 27); 112 System.out.println(wt.getName()+"---"+wt.getAge()); 113 wt.teach(); 114 System.out.println("---------------"); 115 116 //多态测试:因为子类中没有定义特有功能,所以可以多态实现。 117 //基础班老师 118 Teacher t = new BasicTeacher(); 119 System.out.println(t);//BasicTeacher@6d06d69c 120 t.setName("刘意"); 121 t.setAge(30); 122 System.out.println(t.getName()+"---"+t.getAge()); 123 t.teach(); 124 System.out.println("--------------"); 125 126 //对象名没有改哦,因为这是同一个对象此时指向了别的地址。 127 t = new BasicTeacher("刘意", 30); 128 System.out.println(t);//BasicTeacher@7852e922 129 System.out.println(t.getName()+"---"+t.getAge()); 130 t.teach(); 131 System.out.println("--------------"); 132 133 //就业班老师 134 //对象名依旧没有改哦,因为这是同一个对象此时指向了别的地址。 135 t = new WorkTeacher(); 136 System.out.println(t);//WorkTeacher@4e25154f 137 t.setName("林青霞"); 138 t.setAge(27); 139 System.out.println(t.getName()+"---"+t.getAge()); 140 t.teach(); 141 System.out.println("--------------"); 142 143 //对象名依旧依旧没有改哦,因为这是同一个对象此时指向了别的地址。 144 t = new WorkTeacher("林青霞", 27); 145 System.out.println(t);//WorkTeacher@70dea4e 146 System.out.println(t.getName()+"---"+t.getAge()); 147 t.teach(); 148 } 149 } C:学生案例练习 示例代码如下:类同B,不在赘述。 D:员工案例练习 示例代码如下: 1 /* 2 假如我们在开发一个系统时需要对员工类进行设计,员工包含3个属性:姓名、工号以及工资。 3 经理也是员工,除了含有员工的属性外,另为还有一个奖金属性。 4 请使用继承的思想设计出员工类和经理类。要求类中提供必要的方法进行属性访问。 5 --------------------------------------- 6 分析: 7 普通员工类 8 成员变量:姓名、工号以及工资。 9 成员方法:工作 10 经理类: 11 成员变量:姓名、工号以及工资,奖金属性。 12 成员方法:工作 13 --------------------------------------- 14 实现: 15 抽象员工类 16 具体的普通员工类 17 具体的经理类 18 测试类 19 */ 20 21 //定义抽象员工类 22 abstract class Employee { 23 //姓名、工号以及工资 24 private String name; 25 private String id; 26 private int salary; 27 28 public Employee() {} 29 30 public Employee(String name, String id, int salary) { 31 this.name = name; 32 this.id = id; 33 this.salary = salary; 34 } 35 36 public String getName() { 37 return name; 38 } 39 40 public void setName(String name) { 41 this.name = name; 42 } 43 44 public String getId() { 45 return id; 46 } 47 48 public void setId(String id) { 49 this.id = id; 50 } 51 52 public int getSalary() { 53 return salary; 54 } 55 56 public void setSalary(int salary) { 57 this.salary = salary; 58 } 59 60 //工作 61 public abstract void work(); 62 } 63 64 //具体的普通员工类 65 class Programmer extends Employee { 66 public Programmer() {} 67 68 public Programmer(String name, String id, int salary) { 69 super(name, id, salary); 70 } 71 72 public void work() { 73 System.out.println("按照需求写代码"); 74 } 75 } 76 77 //具体的经理类 78 class Manager extends Employee { 79 //奖金 80 private int money; //bonus 奖金 81 82 public Manager() {} 83 84 public Manager(String name, String id, int salary, int money) { 85 super(name, id, salary); 86 this.money = money; 87 } 88 89 public void work() { 90 System.out.println("跟客户谈需求"); 91 } 92 93 public int getMoney() { 94 return money; 95 } 96 97 public void setMoney(int money) { 98 this.money = money; 99 } 100 } 101 102 //测试类 103 class AbstractTest4 { 104 public static void main(String[] args) { 105 //测试具体的普通员工类 106 Employee emp = new Programmer(); 107 emp.setName("林青霞"); 108 emp.setId("czbk001"); 109 emp.setSalary(18000); 110 System.out.println(emp.getName()+"---"+emp.getId()+"---"+emp.getSalary()); 111 emp.work(); 112 System.out.println("-------------"); 113 emp = new Programmer("林青霞", "czbk001", 18000); 114 System.out.println(emp.getName()+"---"+emp.getId()+"---"+emp.getSalary()); 115 emp.work(); 116 System.out.println("-------------"); 117 118 //测试具体的经理类 119 /* 120 emp = new Manager(); 121 emp.setName("刘意"); 122 emp.setId("czbk002"); 123 emp.setSalary(8000); 124 emp.setMoney(2000); 125 */ 126 //由于子类经理类有特有的内容-成员变量-奖金,用多态(父类)测试不合适,所以我们用具体的子类来测试。 127 Manager m = new Manager(); 128 m.setName("刘意"); 129 m.setId("czbk002"); 130 m.setSalary(8000); 131 m.setMoney(2000); 132 System.out.println(m.getName()+"---"+m.getId()+"---"+m.getSalary()+"---"+m.getMoney()); 133 m.work(); 134 System.out.println("-------------"); 135 136 //通过含参构造方法赋值 137 m = new Manager("刘意", "czbk002", 8000, 2000); 138 System.out.println(m.getName()+"---"+m.getId()+"---"+m.getSalary()+"---"+m.getMoney()); 139 m.work(); 140 } 141 } --------------------------------------- (5)抽象类的几个小问题 A:抽象类有构造方法,但是抽象类不能实例化,那么构造方法有什么用? 答:用于子类访问父类数据的初始化。 B:一个类如果没有抽象方法,却定义为抽象类,有什么用? 答:为了不让外界创建该抽象类的对象,要想访问它只能通过该抽象类的子类。 C:abstract不能和哪些关键字共存? a:final 冲突 因为最终方法不能被重写,而抽象的方法需要被具体的子类重写。 final abstract void show(); //错误: 非法的修饰符组合: abstract和private b:private 冲突 因为私有方法不能被继承,所以就不能被重写,而抽象的方法需要被具体的子类重写。 private abstract void show(); //错误: 非法的修饰符组合: abstract和final c:static 无意义 因为抽象方法是没有方法体的,而静态是可以直接通过类名访问的。访问一个没有方法体的方法,意义何在呢? static abstract void show(); //错误: 非法的修饰符组合: abstract和static-----------------------------------------------------------------------------4:接口(掌握) (1)回顾猫狗案例,它们仅仅提供一些基本功能。 部分的猫会钻火圈,狗会跳高等功能,不是动物本身就具备的, 是在后面的培养中训练出来的,所以,为了体现事物功能的扩展性, Java中就提供了接口来定义这些额外功能,并不给出具体实现(说明是抽象方法),将来哪些猫狗需要被培训,只需要这部分猫狗把这些额外功能实现即可。 其实接口是最最抽象的抽象类。--------------------------------------- (2)接口的特点: A:接口用关键字interface修饰 interface 接口名 {} B:类实现接口用implements修饰 class 类名 implements 接口名 {} C:接口不能实例化 那么,接口如何实例化呢? 按照多态的方式来实例化。(即就要去做一个具体的子类,通过具体的子类去实例化) 由此可见,多态有几种方式: 1.具体类多态(几乎没有,但是讲解是通过具体类讲解的) 2.抽象类多态(常用) 3.接口多态(最常用) D:接口的实现类(子类) 接口的实现类格式:接口名+Impl a:接口的实现类是一个抽象类。但是意义不大,因为你是抽象类,最终还得需要具体子类。 //定义动物培训接口 interface AnimalTrain { public abstract void jump(); } //抽象类实现接口 abstract class Dog implements AnimalTrain { } b:接口的实现类是一个具体类,这个类必须重写接口中的所有抽象方法。(推荐方案) //定义动物培训接口 interface AnimalTrain { public abstract void jump(); } //具体类实现接口 class Cat implements AnimalTrain { public void jump() { System.out.println("猫可以跳高了"); } }--------------------------------------- (3)接口的成员特点: A:接口的成员变量特点: 只能是常量,并且是静态的。 因为接口的所有成员变量的默认修饰符都是:public static final 建议自己手动给出。 B:接口的构造方法特点: 接口没有构造方法 。 那么接口的实现类的无参构造方法默认访问的是谁的无参构造呢? 答:所有的类都默认继承一个类:Object类。 因为:类 Object 是类层次结构的根类。每个类都使用 Object 作为超类。 又因为:类 Object 只有无参构造方法,所以后来要求所有子类都默认调用的是父类的无参构造方法。 //接口名+Impl这种格式是接口的实现类格式 /* class InterImpl implements Inter { public InterImpl() { super(); } } */ //上面的写法等价于下面的写法 class InterImpl extends Object implements Inter { public InterImpl() { super(); } } C:接口的成员方法特点: 接口的成员方法只能是抽象的。 因为接口的所有成员方法的默认修饰符都是:public abstract 建议自己手动给出。--------------------------------------- (4)类与类、类与接口、接口与接口的关系 A:类与类的关系 继承关系,只能单继承,不能多继承(只有一个父类),可以多层继承(可以有爷爷)。 class Son extends Father {} //正确 class Son extends Father, Mother {} //错误 B:类与接口的关系 1.实现关系,可以单实现,也可以多实现。(可以多扩展嘛) 2.还可以在继承一个类的同时,实现多个接口。(继承类 Object 嘛) class Son implements Father, Mother {} //正确 class Son extends Object implements Father, Mother {} //正确 C:接口与接口的关系 继承关系,可以单继承,也可以多继承。 小结:Java中的类是单继承的,Java中的接口可以多继承。--------------------------------------- (5)抽象类和接口的区别(自己补齐)? A:成员区别 抽象类: 成员变量:可以有变量,也可以有常量 构造方法:有(用于子类访问父类数据的初始化) 成员方法:可以有抽象方法,也可以有非抽象方法 接口: 成员变量:只可以是常量 构造方法:无 成员方法:只可以是抽象方法 B:关系区别: 类与类: 继承关系,只能单继承和多层继承。 类与接口: 实现关系,可以单实现,也可以多实现。 接口与接口: 继承关系,可以单继承,也可以多继承。 C:设计理念不同 抽象类 被继承体现的是:“is a”的关系,抽象类中定义的是共性功能。 接口 被实现体现的是:“like a”的关系,接口中定义的是扩展功能。--------------------------------------- (6)接口练习: A:猫狗案例,加入跳高功能 共有六个类:(这里将接口理解为最最抽象的类) 跳高接口 动物类 猫类 狗类 有跳高功能的猫类 有跳高功能的狗类 测试类 示例代码如下: 1 /* 2 猫狗案例,加入跳高的额外功能 3 --------------------------------------- 4 分析:从具体到抽象 5 猫类: 6 姓名,年龄 7 吃饭,睡觉 8 狗类: 9 姓名,年龄 10 吃饭,睡觉 11 12 由于有共性功能,所以,我们抽取出一个父类, 13 抽象动物类: 14 姓名,年龄 15 吃饭(); 16 睡觉(){} 17 18 猫类:继承自抽象动物类 19 狗类:继承自抽象动物类 20 21 跳高的额外功能是一个新的扩展功能,所以我们要定义一个接口。 22 接口: 23 跳高 24 25 部分猫类:实现跳高 26 部分狗类:实现跳高 27 --------------------------------------- 28 实现;从抽象到具体 29 跳高接口 30 抽象动物类 31 抽象猫类 32 抽象狗类 33 具体的有跳高功能的猫类 34 具体的有跳高功能的狗类 35 测试类 36 37 使用: 38 使用具有跳高功能的具体类进行测试,因为具有跳高功能的具体类具有最多的功能。 39 */ 40 //定义跳高接口 41 interface Jumpping { 42 //跳高功能 43 public abstract void jump(); 44 } 45 46 //定义抽象动物类 47 abstract class Animal { 48 //姓名 49 private String name; 50 //年龄 51 private int age; 52 53 public Animal() {} 54 55 public Animal(String name, int age) { 56 this.name = name; 57 this.age = age; 58 } 59 60 public String getName() { 61 return name; 62 } 63 64 public void setName(String name) { 65 this.name = name; 66 } 67 68 public int getAge() { 69 return age; 70 } 71 72 public void setAge(int age) { 73 this.age = age; 74 } 75 76 //吃饭(); 77 public abstract void eat(); 78 79 //睡觉(){} 80 public void sleep() { 81 System.out.println("睡觉觉了"); 82 } 83 } 84 85 //具体的猫类 86 class Cat extends Animal { 87 public Cat() {} 88 89 public Cat(String name,int age) { 90 super(name, age); 91 } 92 93 public void eat() { 94 System.out.println("猫吃鱼"); 95 } 96 } 97 98 //具体的狗类 99 class Dog extends Animal { 100 public Dog() {} 101 102 public Dog(String name, int age) { 103 super(name, age); 104 } 105 106 public void eat() { 107 System.out.println("狗吃肉"); 108 } 109 } 110 111 //有跳高功能的具体的猫类 112 class JumpCat extends Cat implements Jumpping { 113 public JumpCat() {} 114 115 public JumpCat(String name, int age) { 116 super(name,age); 117 } 118 119 public void jump() { 120 System.out.println("跳高猫"); 121 } 122 } 123 124 //有跳高功能的具体的狗类 125 class JumpDog extends Dog implements Jumpping { 126 public JumpDog() {} 127 128 public JumpDog(String name, int age) { 129 super(name,age); 130 } 131 132 public void jump() { 133 System.out.println("跳高狗"); 134 } 135 } 136 137 //测试类 138 class InterfaceTest { 139 public static void main(String[] args) { 140 //定义有跳高功能的具体的猫类并测试 141 //法一: 142 JumpCat jc = new JumpCat(); 143 jc.setName("哆啦A梦"); 144 jc.setAge(3); 145 System.out.println(jc.getName()+"---"+jc.getAge()); 146 jc.eat(); 147 jc.sleep(); 148 jc.jump(); 149 150 //法二: 151 JumpCat jc2 = new JumpCat("加菲猫", 2); 152 System.out.println(jc2.getName()+"---"+jc2.getAge()); 153 jc2.eat(); 154 jc2.sleep(); 155 jc2.jump(); 156 System.out.println("-----------------"); 157 158 //定义有跳高功能的具体的狗类并测试 159 //法一: 160 JumpDog jd = new JumpDog(); 161 jd.setName("旺财"); 162 jd.setAge(8); 163 System.out.println(jd.getName()+"---"+jd.getAge()); 164 jd.eat(); 165 jd.sleep(); 166 jd.jump(); 167 168 //法二: 169 jd = new JumpDog("旺财", 8); 170 System.out.println(jd.getName()+"---"+jd.getAge()); 171 jd.eat(); 172 jd.sleep(); 173 jd.jump(); 174 } 175 } B:老师和学生案例,加入抽烟功能 共有六个类:(这里将接口理解为最最抽象的类) 抽烟接口 人类 学生类 老师类 有抽功能的学生类 有抽功能的老师类 测试类 示例代码同上,不在赘述! =============================================================================我的GitHub地址: https://github.com/heizemingjun 我的博客园地址: http://www.cnblogs.com/chenmingjun 我的蚂蚁笔记博客地址: http://blog.leanote.com/chenmingjun Copyright ©2018 黑泽明军 【转载文章务必保留出处和署名,谢谢!】

优秀的个人博客,低调大师

java基础学习_面向对象(下)01_day08总结

==========================================================================================================================================================涉及到的知识点有:1:继承(掌握) (0)Java继承概述 (1)继承定义 (2)Java中如何表示继承呢?格式是什么呢? (3)继承的好处 (4)继承的弊端 A:让类的耦合性增强。这样某个类的改变,就会影响其他和该类相关的类。 B:打破了封装性。 (5)Java中继承的特点 (6)继承的注意事项 A:Java中类只支持单继承,不支持多继承。 B:Java中可以多层(重)继承(继承体系) (7)那么什么时候使用继承呢? A:继承体现的是:is a的关系。 B:采用假设法。 (8)Java继承中的成员关系 A:成员变量 B:构造方法 C:成员方法 (9)方法重写:(方法=成员方法) (10)方法重写的两个面试题 A:Override和Overload的区别?Overload是否可以改变返回值类型? B:this和super的区别和各自的作用? (11)数据初始化的面试题 A:一个类的初始化过程 B:子父类的构造执行过程 C:子父类的初始化(分层初始化) (12)继承案例 A:学生和老师案例 B:猫狗案例的分析和实现==========================================================================================================================================================1:继承(掌握) (0)Java继承概述 (1)继承定义:把多个类中相同的成员给提取出来定义到一个独立的类中。然后让这多个类和该独立的类产生一个关系,这多个类就具备了这些内容。这个关系叫继承。 (2)Java中如何表示继承呢?格式是什么呢? A:用关键字extends表示。 B:格式: class 子类名 extends 父类名 {}--------------------------------------- (3)继承的好处: A:提高了代码的复用性。 B:提高了代码的维护性。 C:让类与类之间产生了一个关系,是多态的前提。 类与类产生了关系,其实也是继承的一个弊端: 类的耦合性增强了。--------------------------------------- (4)继承的弊端: A:让类的耦合性增强。这样某个类的改变,就会影响其他和该类相关的类。 开发设计的原则:低耦合,高内聚。 耦合:类与类之间的关系。 内聚:自己完成某件事情的能力。 B:打破了封装性。 因为我们曾经说过:一个类中的成员尽量不要让外界直接访问,子类继承父类后,那么父类的封装就被打破了。--------------------------------------- (5)Java中继承的特点: A:Java中类只支持单继承,不支持多继承。 即:一个类只能有一个父类,不可以有多个父类。 class Father {} class Mother {} class Son exnteds Father {} //正确的 class Son extends Father,Mother {} //错误的 有些语言是支持多继承的额,比如c++。其格式是:extends 类1,类2,... B:Java中可以多层(重)继承(继承体系) class A {} class B extends A {} class C extends B {}--------------------------------------- (6)继承的注意事项: A:子类不能继承父类的私有成员(成员变量和成员方法)。 其实这也体现了继承的另一个弊端:打破了封装性。 因为我们曾经说过:一个类中的成员尽量不要让外界直接访问,子类继承父类后,那么父类的封装就被打破了。 B:子类不能继承父类的构造方法,但是可以通过super关键字去访问父类构造方法。 因为构造方法比较特殊,谈不上继承,构造方法是对对象进行数据初始化的。 C:不要为了部分功能而去继承。 例如: class A { public void show1(){} public void show2(){} } class B { public void show2(){} public void show3(){} } //我们发现B类中出现了和A类一样的show2()方法,所以,我们就用继承来体现。 class B extends A { public void show3(){} } 这样其实不好,因为这样你不但有了show2(),而且还多了show1()。 有可能show1()不是你想要的。--------------------------------------- (7)那么什么时候使用继承呢? A:继承体现的是:is a的关系。 例如: Person Student Teacher 水果 苹果 香蕉 橘子 B:采用假设法。 假设有两个类A,B。只有他们符合A是B的一种,或者B是A的一种的时候,就可以考虑使用继承。--------------------------------------- (8)Java继承中的成员关系: A:成员变量 a:子类的成员变量名称和父类中的成员变量名称不一样时,这个太简单。 b:子类的成员变量名称和父类中的成员变量名称一样时,这个怎么访问呢? 在子类的方法中访问一个成员变量的查找顺序: 1.在子类方法的局部范围找,有就使用。 2.在子类的成员范围找,有就使用。 3.在父类的成员范围找,有就使用。 4.都找不到,就报错。 B:构造方法 a:子类的所有的构造方法默认都会去访问父类的无参构造方法。 因为子类会继承父类中的数据,可能还会使用父类的数据。 所以,子类初始化之前,一定要先完成父类数据的初始化。 特别注意:其实子类的每一个构造方法的第一条语句默认都是:super(); b:父类中如果没有无参构造方法(也即父类中只给了带参构造方法),子类的构造方法怎么办? 法1:子类的构造方法通过 super(...); 去显示调用父类的带参构造方法。 法2:子类的构造方法通过 this();/this(...); 调用本类的其他的构造方法,但是子类的其他的构造方法中一定会有一个去访问了父类的带参构造方法。 法3:让父类提供无参构造。 注意事项: this();/this(...);/super(...); 这三个语句访问子类或父类的构造方法的时候,必须放在第一句语句上。 否则,就可能会对父类数据进行多次初始化。 C:成员方法 a:子类的成员方法名称和父类中的成员方法名称不一样时,这个太简单。 b:子类的成员方法名称和父类中的成员方法名称一样时,这个怎么访问呢? 通过子类对象访问一个成员方法的查找顺序: 1.在子类的成员方法中找,有就使用。 2.在父类的成员方法中找,有就使用。 3.都找不到,就报错。--------------------------------------- (9)方法重写:(方法=成员方法) 方法重写:子类中出现了和父类中方法声明一模一样的方法(方法名、参数列表和返回值类型都一样),也被称为方法覆盖、方法复写。 方法重载:本类中出现的方法名一样,参数列表不同,与返回值类型无关的方法。 方法重写的使用特点: 如果子类和父类的方法名不同,就调用各自对应的方法。 如果子类和父类的方法名相同,最终使用的是子类自己的方法。 方法重写的应用: 当子类需要父类的功能,而功能的主体子类还有自己特有的内容时,可以重写父类中的方法,这样,即沿袭了父类的功能,又定义了子类自己特有的内容。 方法重写的注意事项: 1.父类中的私有方法不能被重写。 因为父类私有方法子类根本无法继承。 2.子类重写父类方法时,访问权限不能更低。(最好权限要一致。) 默认的权限要小于public的权限。 3.父类的静态方法,子类也必须通过静态方法进行重写。 (其实这个算不上方法重写,但是现象确实如此,至于为什么算不上方法重写,多态中我会讲解。) 因为方法是跟对象相关的,而静态是跟类相关的。 小结:子类重写父类方法的时候,最好声明一模一样。--------------------------------------- (10)方法重写的两个面试题: A:Override和Overload的区别?Overload是否可以改变返回值类型? 方法重写: 在子类中,出现和父类中一模一样的方法声明的现象。(包含方法名、参数列表和返回值类型都一样) 方法重载: 同一个类中,出现的方法名相同,参数列表不同,与返回值类型无关的现象。 方法重载能改变返回值类型,因为它和返回值类型无关。 Override:方法重写 Overload:方法重载 B:this和super的区别和各自的作用? this: 代表当前类的对象引用。 super:代表父类存储空间的标识。(可以理解为父类的引用,通过这个东西可以访问父类的成员。) 应用场景: 成员变量: this.成员变量 super.成员变量 构造方法: this(...) super(...) 成员方法: this.成员方法 super.成员方法--------------------------------------- (11)数据初始化的面试题 A:一个类的初始化过程 先进行成员变量的初始化: 默认初始化 显示初始化 构造方法初始化 B:子父类的构造方法发的执行过程 子类的所有的构造方法默认都会去访问父类的无参构造方法。 C:子父类的初始化(分层初始化) 先进行父类初始化,然后进行子类初始化。--------------------------------------- (12)继承案例: A:学生和老师案例 继承前案例 继承后案例 B:猫狗案例的分析和实现 做设计的时候,先找到具体的事物,然后发现具体的事物的共性,再提取出一个父类。=============================================================================我的GitHub地址: https://github.com/heizemingjun 我的博客园地址: http://www.cnblogs.com/chenmingjun 我的蚂蚁笔记博客地址: http://blog.leanote.com/chenmingjun Copyright ©2018 黑泽明军 【转载文章务必保留出处和署名,谢谢!】

优秀的个人博客,低调大师

java基础学习_基础语法(下)02_day06总结

========================================================================================================================================================== 涉及到的知识点有:1:二维数组(理解) (1)二维数组的定义 (2)二维数组的格式 格式一:(自动动态初始化) 格式二:(半自动动态初始化) 格式三:(静态初始化) 面试题: (3)二维数组的案例(掌握) A:二维数组的遍历 B:二维数组的求和 C:打印杨辉三角形(行数可以键盘录入)2:两个思考题(理解) (1)Java中的参数传递问题及图解。 (2)数据加密问题。 ==========================================================================================================================================================1:二维数组(理解) (1)二维数组的定义:元素是一维数组的数组。 (2)二维数组的格式: 格式一:(自动动态初始化) 数据类型[][] 数组名 = new 数据类型[m][n]; //常用这个格式。 数据类型 数组名[][] = new 数据类型[m][n]; //该格式可以,但是很少用了。 数据类型[] 数组名[] = new 数据类型[m][n]; //该格式也可以,但是很少用了。 m表示这个二维数组有多少个一维数组。 n表示每一个一维数组的元素个数。 举例: int[][] arr = new int[3][2]; 定义了一个二维数组arr。 这个二维数组有3个一维数组,名称是arr[0],arr[1],arr[2]。 每个一维数组有2个元素,可以通过arr[m][n]来获取。 即: arr[m][n] 表示获取第m+1个一维数组的第n+1个元素。 例如:arr[1][2] 表示获取第2个一维数组的第3个元素。 如下如图所示01: --------------------------------------- 格式二:(半自动动态初始化) 数据类型[][] 数组名 = new 数据类型[m][]; m表示这个二维数组有多少个一维数组。 这一次没有直接给出一维数组的元素个数,可以动态的给出。 举例: int[][] arr = new int[3][]; arr[0] = new int[2]; arr[1] = new int[3]; arr[2] = new int[1]; 如下如图所示02: --------------------------------------- 格式三:(静态初始化) 数据类型[][] 数组名 = new 数据类型[][]{ {...}, {...}, {...} }; 数据类型[][] 数组名 = { {...}, {...}, {...} }; 格式三的简化版格式 举例: int[][] arr = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } }; int[][] arr = { { 1, 2, 3 }, { 4, 5 }, { 6 } }; 如下如图所示03: 面试题: 下面定义的区别: int x, y; //定义了1个int类型的变量x,同时也定义了1个int类型的变量y。 //等价于 int x; int y; --------------------------------------- int[] x, y[]; //定义了1个int类型的一维数组x,同时也定义了1个int类型的二维数组y。 //等价于 int[] x; int[] y[]; (3)二维数组的案例(掌握): A:二维数组的遍历 外循环控制的是二维数组的长度,其实就是一维数组的个数。 内循环控制的是一维数组的长度。 public static void printArray2(int[][] arr) { for(int x = 0; x < arr.length; x++) { for(int y = 0; y < arr[x].length; y++) { System.out.print(arr[x][y]+" "); } System.out.println(); } } B:二维数组的求和 int sum = 0; for(int x = 0; x < arr.length; x++) { for(int y = 0; y < arr[x].length; y++) { sum += arr[x][y]; } } C:打印杨辉三角形(行数可以键盘录入) 1 /* 2 需求:打印杨辉三角形(行数可以键盘录入) 3 4 1 5 1 1 6 1 2 1 7 1 3 3 1 8 1 4 6 4 1 9 1 5 10 10 5 1 10 11 分析:看这种图像的规律: 12 A:任何一行的第一列和最后一列都是1。 13 B:从第三行开始,除去第一列和最后一列,剩余的每一列的数据是它上一行的前一列和它上一行的本列之和。 14 15 步骤: 16 A:首先定义一个二维数组。行数如果是n,我们把列数也先定义为n。 17 这个n的数据来自于键盘录入。 18 B:给这个二维数组任何一行的第一列和最后一列赋值为1。 19 C:按照规律给其他元素赋值: 20 从第三行开始,除去第一列和最后一列,剩余的每一列的数据是它上一行的前一列和它上一行的本列之和。 21 D:遍历这个二维数组。 22 */ 23 import java.util.Scanner; 24 25 class Array2Test3 { 26 public static void main(String[] args) { 27 //创建键盘录入对象。 28 Scanner sc = new Scanner(System.in); 29 30 //这个n的数据来自于键盘录入。 31 System.out.println("请输入一个数据:"); 32 int n = sc.nextInt(); 33 34 //定义二维数组 35 int[][] arr = new int[n][n]; 36 37 //给这个二维数组任何一行的第一列和最后一列赋值为1 38 for(int x = 0; x < arr.length; x++) { 39 arr[x][0] = 1; //任何一行第一列 40 arr[x][x] = 1; //任何一行的最后一列 41 } 42 43 //按照规律给其他元素赋值 44 //从第三行开始,除去第一列和最后一列,剩余的每一列的数据是它上一行的前一列和它上一行的本列之和。 45 for(int x = 2; x < arr.length; x++) { 46 //这里如果 y <= x 是有个小问题的,就是最后一列的问题,因为最后一列已经给过值了。 47 //所以这里要减去1 48 //并且y也应该从1开始,因为第一列也给过值了。 49 for(int y = 1; y <= x - 1; y++) { 50 //除去第一列和最后一列,剩余的每一列的数据是它上一行的前一列和它上一行的本列之和。 51 arr[x][y] = arr[x - 1][y - 1] + arr[x - 1][y]; 52 } 53 } 54 55 //遍历这个二维数组。 56 /* 57 for(int x = 0; x < arr.length; x++) { 58 for(int y = 0; y < arr[x].length; y++) { 59 System.out.print(arr[x][y]+"\t"); 60 } 61 System.out.println(); 62 } 63 */ 64 //这个时候,要注意了,内循环的变化必须和曾经讲过的九九乘法表类似。 65 for(int x = 0; x < arr.length; x++) { 66 for(int y = 0; y <= x; y++) { 67 System.out.print(arr[x][y]+"\t"); 68 } 69 System.out.println(); 70 } 71 } 72 } -----------------------------------------------------------------------------2:两个思考题(理解) (1)Java中的参数传递问题及图解。 基本类型:形式参数的改变对实际参数没有影响。 引用类型:形式参数的改变直接影响实际参数。 基本类型:传递的是基本类型的数据值。 引用类型:传递的是地址值。 小结:不管怎么说,都是值,即在Java中,只有值传递。 如下图所示04: (2)数据加密问题。 综合的小案例。 int index = 0; arr[index] = number % 10 = number / 1 % 10; index++; arr[index] = number / 10 % 10 = number / 10 % 10; index++; arr[index] = number / 10 / 10 % 10 = number /100 % 10; ...... --------------------------------------- int index = 0; while (number > 0) { arr[index] = number % 10; number /= 10; } 示例代码如下: 1 /* 2 把刚才的代码改进一下: 3 A:把数据改进为键盘录入 4 B:把代码改进为方法实现 5 6 7 另一个数据的测试: 8 number:1234567 9 第一步:7654321 10 第二步:2109876 11 第三步:6109872 12 13 知识点: 14 变量 15 数据类型 16 运算符 17 键盘录入 18 语句 19 方法 20 数组 21 */ 22 import java.util.Scanner; 23 24 class JiaMiDemo2 { 25 public static void main(String[] args) { 26 //创建键盘录入对象 27 Scanner sc = new Scanner(System.in); 28 29 //请输入一个数据 30 System.out.println("请输入一个数据(小于8位):"); 31 int number = sc.nextInt(); 32 33 //写功能实现把number进行加密 34 //调用 35 String result = jiaMi(number); 36 System.out.println("加密后的结果是:"+result); 37 } 38 39 /* 40 需求:写一个功能,把数据number实现加密。 41 两个明确: 42 返回值类型:String 为了做一个字符串的拼接。 43 参数列表:int number 44 */ 45 public static String jiaMi(int number) { 46 //定义数组 47 int[] arr = new int[8]; 48 49 //定义索引 50 int index = 0; 51 52 //把number中的数据想办法放到数组中 53 while(number > 0) { 54 arr[index] = number % 10; 55 index++; 56 number /= 10; 57 } 58 59 //把每个数据加5,然后对10取得余数 60 for(int x = 0; x < index; x++) { 61 arr[x] += 5; 62 arr[x] %= 10; 63 } 64 65 //把第一位和最后一位交换 66 int temp = arr[0]; 67 arr[0] = arr[index - 1]; 68 arr[index - 1] = temp; 69 70 //把数组的元素拼接成一个字符串返回 71 //定义一个空内容字符串 72 String s = ""; 73 74 for(int x = 0; x < index; x++) { 75 s += arr[x]; 76 } 77 78 return s; 79 } 80 } =============================================================================我的GitHub地址: https://github.com/heizemingjun 我的博客园地址: http://www.cnblogs.com/chenmingjun 我的蚂蚁笔记博客地址: http://blog.leanote.com/chenmingjun Copyright ©2018 黑泽明军 【转载文章务必保留出处和署名,谢谢!】

优秀的个人博客,低调大师

java基础学习_基础语法(下)01_day05总结

========================================================================================================================================================== 涉及到的知识点有:1:方法(掌握) (1)方法的定义 (2)方法的格式 (3)如何写一个方法呢?两个明确 (4)如何进行方法调用呢? A:有明确返回值的方法调用的方式 B:没有明确返回值的方法调用的方式:(即用void类型修饰的方法调用) (5)方法的案例 (6)方法的注意事项 (7)方法的重载 (8)方法重载的案例2:数组(一维数组)(掌握) (1)数组的定义 (2)数组的特点 (3)数组的定义格式 (4)数组的初始化方式 A:动态初始化 B:静态初始化(常用) (5)Java语言的内存分配 (6)数组的内存图解 (7)数组操作时的两个常见小问题 (8)数组的常见操作 A:数组的遍历 方式1 方式2 B:数组的最值 最大值 最小值 C:数组的逆序(逆置) 方式1://使用一个索引,需要考虑到变量的变化。 方式2://使用两个索引,不用考虑变量变化。 D:数组的查表(根据键盘录入索引,查找对应星期) E:数组的元素查找(查找指定元素第一次在数组中出现的索引) ==========================================================================================================================================================1:方法(掌握) (1)方法的定义:就是完成特定功能的代码块。 注意:在很多语言里面有函数的定义,而在Java中,函数被称为方法。 (2)方法的格式: 修饰符 返回值类型 方法名(参数类型 参数名1, 参数类型 参数名2, 参数类型 参数名3...) { 方法体语句; ---------------------------------------------------- return 返回值; 参数列表 } --------------------------------------- 修饰符:目前就用 public static。后面再详细讲解其他修饰符。 返回值类型:就是功能结果的数据类型。 方法名:就是起了一个名字,符合命名规则即可,方便我们调用该方法。 参数类型:就是参数的数据类型。限定调用方法时传入参数的数据类型。 参数名:就是变量名,接收调用方法时传入的参数。 参数分类: 实际参数(实参):实际参与运算的数据。 形式参数(形参):方法上定义的,用于接收实际参数的变量。 方法体语句:就是完成功能的代码。 return:结束方法以及返回方法指定类型的值。 返回值:就是功能的结果,由return带给调用者。 (3)如何写一个方法呢?两个明确: a:返回值类型:明确功能结果的数据类型。 b:参数列表:明确参数的个数以及参数的数据类型。 (4)如何进行方法调用呢? A:有明确返回值的方法调用的方式: a:单独调用,没有意义。 sum(x, y); b:输出调用,但是不够好,因为我不一定非要把结果输出,可能针对结果进行进一步操作。但是讲课一般我就用了。 System.out.println(sum(x, y)); c:赋值调用,推荐方式。 int z = sum(x, y); 如下图所示01: B:没有明确返回值的方法调用的方式:(即用void类型修饰的方法调用) a:只能单独调用。 (5)方法的案例: A:求和方案。 B:获取两个数中的较大值。(返回值是int类型,用三元改进。) C:比较两个数据是否相同。(返回值是boolean类型,用三元改进。) D:获取三个数中的最大值。(返回值是int类型,用if else嵌套,用三元改进。) E:输出m行n列的星形。(返回值是void类型。) F:键盘录入一个数据n(1<=n<=9),输出对应的nn乘法表。 (6)方法的注意事项: A:方法不调用不执行。 B:方法与方法是平级关系,不能嵌套定义。 C:方法在定义的时候,参数是用逗号,隔开的 D:方法在调用的时候,不用在传递数据的类型。 E:如果方法有明确的返回值类型,就必须有return语句返回。 (7)方法的重载 在同一个类中,方法名相同,参数列表不同。与返回值无关。 参数列表不同: 参数的个数不同。 参数的对应的数据类型不同。 (8)方法重载的案例 不同的类型的多个同名方法的比较。----------------------------------------------------------------------------- 2:数组(一维数组)(掌握) (1)数组的定义:存储同一种数据类型的多个元素(变量)的容器(集合)。 (2)数组的特点:每一个元素都有编号,从0开始,最大编号是长度-1。 编号的专业叫法:索引(角标)。 数组既可以存储基本数据类型,也可以存储引用数据类型。 (3)数组的定义格式: A:数据类型[] 数组名; int[] a; //定义了一个int类型的数组a变量。 B:数据类型 数组名[]; int a[]; //定义了一个int类型的a数组变量。 --------------------------------------- 推荐是用A方式,A方式的可读性更强,B方法就忘了吧。在Java中均可。 B方式早期的时候确实有很多人这样用。不过,现在这样用的人越来越少了。 作为Java的粉丝C#(Java的模仿者)就不再支持第二种语法格式了。越来越多的语言可能会抛弃第二种格式。 但是看源码的时候要能看懂。 (4)数组的初始化方式: Java中的数组必须先初始化,然后才能使用。 所谓初始化:就是为数组中的数组元素分配内存空间,并为每个数组元素赋值。 A:动态初始化 只指定数组长度,由系统分配初始值。(数组长度其实就是数组中元素的个数。) 举例: int[] arr = new int[3]; System.out.println(arr); //[I@6d06d69c 地址值,数组名其实就是该数组首元素的地址。 B:静态初始化(常用) 给初值,由系统决定数组长度。 举例: int[] arr = new int[]{ 1, 2, 3 }; 简化版:int[] arr = { 1, 2 ,3 }; 如下图所示06: (5)Java语言的内存分配: Java程序在运行时,需要在内存中的分配空间。 为了提高运算效率,就对空间进行了不同区域的划分,因为每一片区域都有特定的处理数据方式和内存管理方式。 A:栈:存储局部变量。 B:堆:存储所有new出来的东西。 C:方法区(面向对象部分详细讲解) D:本地方法区(系统相关) E:寄存器(CPU使用) --------------------------------------- 注意: a:局部变量:在方法定义中或者方法声明上定义的变量。使用完毕,立即消失。 b:栈内存和堆内存的区别: 栈:数据使用完毕,就消失。 堆:每一个new出来的东西都有地址。 堆中的每一个变量都有默认值。 byte,short,int,long --> 0 float,double --> 0.0 char --> '\u0000' //因为Java语言采用的是Unicode编码。 boolean --> false 引用类型 --> null 在Java语言中,数据使用完毕后,就变成垃圾了,但并没有立即回收,会在垃圾回收器空闲的时候回收。 在C++语言中,有构造函数和析构函数,调用析构函数用来释放空间。 如下图所示02: (6)数组的内存图解: A:一个数组 B:二个数组 C:三个数组(两个栈变量指向同一个堆内存) 如下图所示03/04/05: (7)数组操作时的两个常见小问题: a:ArrayIndexOutOfBoundsException:数组索引越界异常。 原因:你访问了不存在的索引。 b:NullPointerException:空指针异常。 原因:数组已经不再指向堆内存了。而你还用数组名去访问元素。(即:数组引用没有指向实体,却在操作实体中的元素。) (8)数组的常见操作:--------------------------------------- A:数组的遍历 数组的一个属性:获取数值长度:数值名.length 方式1: public static void printArray(int[] arr) { for(int x = 0; x < arr.length; x++) { System.out.println(arr[x]); } } 方式2:通过字符串的拼接,让元素在一行上输出。 public static void printArray(int[] arr) { System.out.print("[ "); for(int x = 0; x < arr.length; x++) { if(x == arr.length - 1) { System.out.println(arr[x]+" ]"); }else { System.out.print(arr[x]+", "); } } }--------------------------------------- B:数组的最值 最大值: public static int getMax(int[] arr) { int max = arr[0]; for(int x = 1; x < arr.length; x++) { if(arr[x] > max) { max = arr[x]; } } return max; } 最小值: public static int getMin(int[] arr) { int min = arr[0]; for(int x = 1; x < arr.length; x++) { if(arr[x] < min) { min = arr[x]; } } return min; }--------------------------------------- C:数组的逆序(逆置) 方式1://使用一个索引,需要考虑到变量的变化。 public static void reverse(int[] arr) { for(int x = 0; x < arr.length / 2; x++) { int temp = arr[x]; arr[x] = arr[arr.length - 1 - x]; arr[arr.length - 1 - x] = temp; } } 方式2://使用两个索引,不用考虑变量变化。 public static void reverse(int[] arr) { for(int start = 0, end = arr.length - 1; start <= end; start++, end--) { int temp = arr[start]; arr[start] = arr[end]; arr[end] = temp; } }--------------------------------------- D:数组的查表(根据键盘录入索引,查找对应星期) public static String getString(String[] strArray, int index) { return strArray[index]; } E:数组的元素查找(查找指定元素第一次在数组中出现的索引) 方式1: public static int getIndex(int[] arr, int value) { for(int x = 0; x < arr.length; x++) { if(arr[x] == value) { return x; } } return -1; //找不到的时候对应的返回的值。或者是for循环的判断条件语句为false时候对应的方茴的值。 } 特别注意:只要是判断条件语句,就有可能是false,所以要细心!!! 方式2: public static int getIndex(int[] arr, int value) { int index = -1; for(int x = 0; x < arr.length; x++) { if(arr[x] == value) { index = x; break; } } return index; }=============================================================================我的GitHub地址: https://github.com/heizemingjun 我的博客园地址: http://www.cnblogs.com/chenmingjun 我的蚂蚁笔记博客地址: http://blog.leanote.com/chenmingjun Copyright ©2018 黑泽明军 【转载文章务必保留出处和署名,谢谢!】

优秀的个人博客,低调大师

java基础学习_基础语法(上)03_day04总结

========================================================================================================================================================== 涉及到的知识点有:1:switch语句(掌握)2:循环语句(掌握)3:循环结构(循环嵌套使用)4:控制跳转语句(掌握) ==========================================================================================================================================================1:switch语句(掌握) (1)格式: switch(表达式) { case 值1: 语句体1; break; case 值2: 语句体2; break; ...... ...... case 值n: 语句体n; break; default: 语句体n+1; break; //该break可以省略。 } 格式解释说明: switch:说明这是switch语句。 表达式:可以是byte,short,int,char。 JDK5以后表达式可以是枚举。 JDK7以后表达式可以是字符串。 case:后面的值就是要和表达式进行比较的值。 语句体部分:可以是一条或多条语句。 break:表示程序到这里中断,跳出switch语句了。 default:如果所有的情况都不匹配,就执行这里的,相当于if语句中的else。 (2)面试题: switch语句的表达式可以是byte吗?可以是long吗?可以是String吗? 可以,不可以,JDK7以后可以。 (3)执行流程: A:首先,计算表达式的值; B:其次,和每一个case的值进行匹配,如果有就执行对应的语句体,看到break就结束。 C:如果没有匹配,就执行default的语句体n+1。 (4)注意事项: A:case后面只能是常量,不能是变量;而且,多个case后面的值不能出现相同的。 B:default可以省略吗? 可以省略,但是不建议,因为它的作用是对不正确的情况给出提示。 特殊情况: case就可以把值固定(即:判断的值是固定的)。 例如:做单选题:A,B,C,D只有四个选项。 C:break可以省略吗? default后面的break可以省略。但是其余case后面的break不可以省略,否则出现的结果可能不是我们想要的。 即:会出现一个现象:case穿透。 最终我们建议都不要省略。 D:default一定要在最后吗? 不是,可以在任意位置。但是建议放在最后。因为default表示其它的情况。也即:default不是程序结束的标志。 E:switch语句的两种结束标志: a:遇到break就表示结束了。 b:如果一直没有遇到break,那就执行到程序的末尾才表示结束了。 特别注意一个情况:如下图所示01: (5)案例: A:键盘录入一个数字(1-7),输出对应的星期几。(表达式是byte,int,short的情况) B:单项选择题。(表达式是char的情况) //由于我们现在没有办法键盘录入得到一个'A','B','C','D' //此时需要强制转换为字符类型。 Scanner sc = new Scanner(System.in); int choiceNumber = sc.nextInt(); char choice = (char) choiceNumber; C:键盘录入一个字符串的问题。(表达式是字符串的情况) String s = sc.nextLine(); D:根据给定的月份,输出对应的季节。(可以使用case穿透简化代码) (6)if语句和switch语句各自的使用场景: A:if语句 针对boolean类型的判断。 针对一个范围的判断。 针对几个常量的判断。 B:switch语句 针对几个常量的判断。-----------------------------------------------------------------------------2:循环语句(掌握) (1)有三种:for循环,while循环,do...while循环。 注意:反复执行这个循环体时,需要在合适的时候把循环判断条件修改为false,从而结束循环。--------------------------------------- (2)for循环语句 A:格式: for(初始化语句;判断条件语句;控制条件语句) { 循环体语句; } 执行流程: a:执行初始化语句(只做一次); b:执行判断条件语句; 如果这里是true,就继续。 如果这里是false,循环就结束。 c:执行循环体语句; d:执行控制条件语句; e:回到b继续。 B:注意事项: a:判断条件语句无论是简单还是复杂,结果都是boolean类型。 b:循环体语句如果是一条,可以省略大括号,但是不建议省略。 c:一般来说:有分号就没有左大括号,有左大括号就没有分号。 C:案例: a:输出10次HelloWorld。 b:输出1-10的数据。 c:输出10-1的数据。 d:求1-10的和。(循环的求和思想)如下图所示02: e:求1-100的和,求1-100的偶数和,求1-100的奇数和。 f:求5的阶乘。 n! = n * (n - 1)! n! = n * (n - 1) *(n -2) * (n - 3) * ... * 3 * 2 * 1 g:在控制台打印水仙花数。 何为水仙花数?答:一个三位数,其各位数字的立方和等于该数本身。 ge: 153/1%10 = 3 shi: 153/10%10 = 5 bai: 153/100%10 = 1 qian: x/10000%10 wan: x/10000%10 ...... 小结: 如果想把某数的个位取出来,就用该数除以1取整后再对10取余; 如果想把某数的十位取出来,就用该数除以10取整后再对10取余; 如果想把某数的百位取出来,就用该数除以100取整后再对10取余; 其余位以此类推。 h:统计水仙花个数。 循环的统计思想。 i:改进版的回文数。 一个五位数:12621 个位 = 万位 十位 = 千位 个位 + 十位 + 千位 + 万位 = 百位 j:统计1-1000之间同时满足如下条件的数据有多少个。 x%3==2 x%5==3 x%7==2--------------------------------------- (3)while循环 A:基本格式: while(判断条件语句) { 循环体语句; } --------------------------------------- 扩展格式: 初始化语句; while(判断条件语句) { 循环体语句; 控制条件语句; } --------------------------------------- for(初始化语句;判断条件语句;控制条件语句) { 循环体语句; } --------------------------------------- 通过查看这个格式,我们就知道while循环可以和for循环等价转换。 B:while的练习: 把for语句的练习用while改进。 C:for和while的区别: a:使用上的区别: 如果想在循环结束后,继续使用控制条件语句所控制的那个变量,用while循环,否则用for循环。不知道的时候用for循环。 因为变量要及早的从内存中消失,可以提高内存的使用效率。 b:理解上的区别: for适合于一个范围内的判断。 while适合次数不明确的判断。 举例:吃葡萄。 D:案例: a:珠穆朗玛峰问题。(不知道次数用while) b:小芳存钱问题(break以后才能做)。--------------------------------------- (4)do...while循环 A:基本格式: do { 循环体语句; }while(判断条件语句); --------------------------------------- 扩展格式: 初始化语句; do { 循环体语句; 控制条件语句; }while(判断条件语句); --------------------------------------- for(初始化语句;判断条件语句;控制条件语句) { 循环体语句; } --------------------------------------- 通过查看格式,我们就可以看出其实三种循环的格式可以是统一的。 B:三种循环的区别: a:do...while循环至少执行一次循环体。 b:for和while必须先判断条件是否是true,然后才能决定是否执行循环体。 c:我们一般优先考虑for,其次考虑while,最后考虑do...while。--------------------------------------- (5)循环使用的注意事项(死循环) A:一定要注意修改控制条件语句,否则容易出现死循环。 B:最简单的死循环格式: a:while(true){...} b:for(;;){...}-----------------------------------------------------------------------------3:循环结构(循环嵌套使用) 循环嵌套:循环语句的循环体本身就是一个循环语句。 (1)请输出一个4行5列的星星(*)图案. ***** ***** ***** ***** for (int x = 0; x < 4; x++) { //外循环控制行数。 for (int y = 0; y < 5; y++) { //内循环控制列数。 System.out.print("*"); } System.out.println(); } (2)请输出如下图形. * ** *** **** ***** for (int x = 0; x < 5; x++) { //外循环控制行数。 for (int y = 0; y <= x; y++) { //内循环控制列数。 System.out.print("*"); } System.out.println(); } (3)在控制台输出九九乘法表。 * ** *** **** ***** ****** ******* ******** ********* for (int x = 0; x < 9; x++) { //外循环控制行数。 for (int y = 0; y <= x; y++) { //内循环控制列数。 System.out.print("*"); } System.out.println(); } --------------------------------------- 1*1=1 1*2=2 2*2=4 1*3=3 2*3=6 3*3=9 1*4=4 2*4=8 3*4=12 4*4=16 ... ... ... ... ... 1*9=9 2*9=18 3*9=27 4*9=36 ... for (int x = 1; x <= 9; x++) { //外循环控制行数。 for (int y = 1; y <= x; y++) { //内循环控制列数。 System.out.print(y+"*"+x+"="+y*x+"\t"); } System.out.println(); } (4)注意事项: '\x' x表示任意,这种做法叫转移字符。 '\t' tab键的位置 '\r' 回车(回到旧行的开端) '\n' 换行(换到新行的开端)----------------------------------------------------------------------------- 4:控制跳转语句(掌握) (1)break:中断的意思 A:用在循环(loop)语句中加入了if判断的情况和switch语句中,离开此应用场景无意义。 B:作用: a:跳出单层循环。 b:跳出多层循环,需要与标签语句的配合。即给循环起个名字。但是呢,几乎不用,跳出多层循环。应用:break配合标签使用,可以通过内循环控制外循环。 格式:标签名:语句 例如: wc:for(int x = 0; x < 3; x++) { nc:for(int y = 0; y < 4; y++) { if(y == 2) { //break nc; break wc; } System.out.print("*"); } System.out.println(); }--------------------------------------- (2)continue:继续的意思 A:用在循环中,离开此应用场景无意义。 B:作用: break:跳出单层循环,循环结束,不在继续下去了。 continue:跳出一次单层循环,但循环没有结束,继续下一次循环。特别注意:在while循环的循环体中使用continue,可能使程序停不下来。 C:填空题 (1) for(int x = 1; x < 10; x++) { if(x == 3) { //break; //1 2 continue; //1 2 4 5 6 7 8 9 } System.out.println(x); } (2) for(int x = 1; x <= 10; x++) { if(x%3 == 0) { //在此处填写代码 } System.out.println(“Java基础班”); } 如何让控制台输出2次:Java基础班 break; 如何让控制台输出7次:Java基础班 continue; 如何让控制台输出13次:Java基础班 System.out.println(“Java基础班”);--------------------------------------- (3)return:返回的意思 return关键字不是为了跳转出循环体,更常用的功能是结束一个方法,也就是退出一个方法。 A:用于结束方法的,后面还会在继续讲解和使用。 B:一旦遇到return,程序就不会在继续往后执行。--------------------------------------- (4)用while语句和break结合使用:小芳存钱案例。 1 /* 2 需求:小芳的妈妈每天给她2.5元钱,她都会存起来,但是, 3 每当这一天是存钱的第5天或者5的倍数的话,她都会花去6元钱, 4 请问,经过多少天,小芳才可以存到100元钱。 5 分析: 6 A:小芳的妈妈每天给她2.5元钱。 7 double dayMoney = 2.5; 8 B:她都会存起来 9 double daySum = 0; 10 C:从第一天开始存储。 11 int dayCount = 1; 12 D:经过多少天,小芳才可以存到100元钱。 13 double result = 100; 14 E:这一天是存钱的第5天或者5的倍数的话,她都会花去6元钱, 15 说明要判断dayCount的值,如果对5整除就减去6元钱。 16 daySum -= 6; 17 由此还隐含了一个问题,就是要判断dayCount的值,如果不是5的倍数天的话,钱要累加。 18 daySum += dayMoney; 19 F:因为不知道是多少天,所以我用死循环,一旦超过100元我就退出循环。 20 */ 21 class WhileDemo { 22 public static void main(String[] args) { 23 //每天要存储的钱是2.5元 24 double dayMoney = 2.5; 25 26 //存钱的初始化值是0 27 double daySum = 0; 28 29 //从第一天开始存储 30 int dayCount = 1; 31 32 //最终存储不小于100就不存储了 33 int result = 100; 34 35 //因为不知道是多少天,所以我用死循环, 36 while(true) { 37 //累加钱 38 daySum += dayMoney; 39 40 //一旦超过100元我就退出循环。 41 if(daySum >= result) { 42 System.out.println("共花了"+dayCount+"天存储了100元"); 43 break; 44 } 45 46 if(dayCount%5 == 0) { 47 //花去6元钱 48 daySum -= 6; 49 System.out.println("第"+dayCount+"天花了6元钱"); 50 } 51 52 //天数变化 53 dayCount++; 54 } 55 } 56 } =============================================================================我的GitHub地址: https://github.com/heizemingjun 我的博客园地址: http://www.cnblogs.com/chenmingjun 我的蚂蚁笔记博客地址: http://blog.leanote.com/chenmingjun Copyright ©2018 黑泽明军 【转载文章务必保留出处和署名,谢谢!】

优秀的个人博客,低调大师

java基础学习_基础语法(上)02_day03总结

========================================================================================================================================================== 涉及到的知识点有:0:基本概念概述 1:运算 2:运算符 3:操作数 4:表达式1:运算符(掌握) (1)算术运算符(掌握) (2)赋值运算符(掌握) (3)比较(关系)运算符(掌握) (4)逻辑运算符(掌握) (5)位运算符(了解) (6)三元(三目/条件)运算符(掌握)2:键盘录入(掌握)3:流程控制语句4:if语句(掌握) (1)三种格式: (2)注意事项: (3)案例: (4)三元运算符和if语句第二种格式的关系: ==========================================================================================================================================================0:基本概念概述 1:运算 对常量和变量进行操作的过程称为运算。 2:运算符 对常量和变量进行操作的符号称为运算符。 3:操作数 参与运算的数据称为操作数 4:表达式 用运算符把常量或者变量连接起来符合java语法的式子就可以称为表达式。 不同运算符连接的式子体现的是不同类型的表达式。 举例: int a = 3 + 4; 这是做了一个加法运算。 +就是运算符,且是算术运算符,我们还有其他很多的运算符。 3,4就是参与运算的操作数据。 3 + 4整体其实就是一个算数表达式。-----------------------------------------------------------------------------1:运算符(掌握) (1)算术运算符(掌握) A:+, -, *, /, %, ++, -- B:+的用法: a:加法; b:正号; c:字符串连接(拼接)符。 例如:System.out.println("x="+x+",y="+y);如下如图所示00: C:/和%的区别: 数据做除法操作的时候,/取得是商,%取得是余数。如下图所示01: D:++和--的用法: a:他们的作用是:对变量进行自增1或者自减1。 b:使用: **单独使用时: 放在操作数据的前面和后面效果是一样。 即:a++或者++a效果一样。 **参与操作使用时: 放在操作数的前面时:先自增1或者自减1,再参与操作。 int a = 10; int b = ++a; //a = 11; b = 11; 放在操作数的后面时:先参与操作,再自增1或者自减1。 int a = 10; int b = a++; //b = 10; a = 11;如下图所示02/03: --------------------------------------- (2)赋值运算符(掌握) A: 基本的赋值运算符:= 把=右边的数据赋值给左边。 扩展的赋值运算符:+=, -=, *=, /=, %=, 等等。 += 把左边和右边数据做加法后,然后将结果赋值给左边。 B:=叫做赋值运算符,也是最基本的赋值运算符。 int x = 10; //把10赋值给int类型的变量x。 C:扩展的赋值运算符的特点: 扩展的赋值运算符隐含了自动强制转换。 即:s += 1; 不是等价于 s = s + 1; 而是等价于 s = (s的数据类型)(s + 1); 面试题: short s = 1; //编译有问题,报错,可能损失精度。 s = s + 1; //short类型参与运算的时候默认转换为int类型。而把int类型赋值给short类型会有问题。 short s = 1; //没有问题。 s += 1; //因为+=隐含了自动强制转换。 请问上面的代码哪个有问题?--------------------------------------- (3)比较(关系)运算符(掌握) A:==, !=, >, >=, <, <=, instanceof(后面讲) B:无论运算符两端是简单还是复杂最终结果是boolean类型。 C:千万不要把==写成了=了。 D:>=, <=只要有一个满足即可,即:不管是大于,还是等于;或者不管是小于,还是等于。如下图所示04: --------------------------------------- (4)逻辑运算符(掌握) A: &, |, ^, !, &&, ||如下图所示05: B:逻辑运算符用于连接boolean类型的表达式,在java中不可以写成3<x<6,而是应该写成x>3&x<6。 表达式:用运算符把常量或者变量连接起来符合java语法的式子就可以称为表达式。 例如: 算术表达式:a + b 比较表达式:a == b C:结论: 逻辑与&:有false则false。 逻辑或|:有true则true。 逻辑异或^:相同则false,不同则true。 举例情侣关系:男男为false,女女为false,男女为true,女男为true。 逻辑非!:非true则false,非false则true。 偶数个叹号!不改变布尔类型,奇数个叹号!改变类型。 逻辑双与&&:最终的结果和&是一样的,只不过有短路效果。只要左边是false,右边就不执行。 逻辑双或||:最终的结果和|是一样的,只不过有短路效果。只要左边是true,右边就不执行。 所以双与(双或)的效率更高!!! 小结:在开发中常用的逻辑运算符为:&&, ||, ! 。--------------------------------------- (5)位运算符(了解) 因为我们一般是做十进制的运算的,而位运算是做的二进制的运算,所以我们一般不需要掌握,但是需要听懂! 因为在底层源码中看大量看到位运算,因为我们的所有的操作在计算机底层都会变成为位运算。可以提高程序的效率。如下如所示06: 要做位运算,首先要把数据转换为二进制。而且还得是补码。如下图所示07: A:^异或位运算符的特殊用法: 一个数据针对另一个数据位异或两次,该数据本身不变。应用:可以对数据做一个简单的加密。如下图所示08: B:面试题: 以后讲课过程中,若没有明确说明数据类型的话,一般默认int类型。 a:请实现两个int变量的交换。int a = 10; int b = 20; 法一:采用第三方变量(开发中用)。 int c = a; a = b; b = c; 法二:用位异或运算符(面试中用)。简记为:等号左边a,b,a 等号右边a^b a = a ^ b; b = a ^ b; //a ^ b ^ b = a = b a = a ^ b; //a ^ b ^ a = b = a 法三:用变量相加的方法。 a = a + b; b = a - b; //a + b - b = a = b a = a - b; //a + b - a = b = a 法四:一句话搞定。 b = (a + b) - (a = b); //b = a + b - b = a b:请用最有效率的方式计算出2乘以8的结果 2<<3如下图所示09/10: --------------------------------------- (6)三元(三目/条件)运算符(掌握) 单目运算符:~3 双目运算符:3 + 4 A:三目运算符格式: 比较表达式? 表达式1 : 表达式2; B:执行流程: 首先计算比较表达式的值,看是true还是false。 如果是true,表达式1就是结果。 如果是false,表达式2就是结果。 C:案例: a:获取两个数据中的最大值。 int max = ((x > y)? x : y); b:获取三个数据中的最大值。 法一: int tmpe = ((a > b)? a : b); int max = ((tmpe > c)? tmpe : c); 法二: int max = (a > b)? ((a > c)? a : c) : ((b > c)? b : c); //三目运算符的嵌套使用。 c:比较两个数据是否相等。 法一: boolean flag = ((a == b)? true : flase); //这样写太啰嗦了。 法二: boolean flag = (a == b); 如下图所示11: ----------------------------------------------------------------------------- 2:键盘录入(掌握) (1)实际开发中,数据是变化的,为了提高程序的灵活性,我们加入键盘录入数据。 (2)如何实现键盘录入数据呢?目前就记住: A:导包: import java.util.Scanner; 位置:在class定义的上边。 B:创建键盘录入对象: Scanner sc = new Scanner(System.in); C:通过对象获取数据: int x = sc.nextInt(); (3)把三元运算符的案例加入键盘录入改进。-----------------------------------------------------------------------------3:流程控制语句 (1)顺序结构:从上往下,依次执行。 (2)选择结构:按照不同的选择,执行不同的代码。 (3)循环结构:做一些重复的代码。 选择结构也称为分支结构。Java语言提供了两种选择结构语句。 1)if语句。 2)switch语句。-----------------------------------------------------------------------------4:if语句(掌握) (1)三种格式: A:格式1: if(比较/关系表达式) { 语句体; } 执行流程: 判断比较表达式的值,看是true还是false。 如果是true,就执行语句体。 如果是false,就不执行语句体。--------------------------------------- B:格式2 if(比较表达式) { 语句体1; }else { 语句体2; } 执行流程: 判断比较表达式的值,看是true还是false。 如果是true,就执行语句体1。 如果是false,就执行语句体2。 if语句的第二种格式与三元运算符的区别如下图所示12: --------------------------------------- C:格式3 if(比较表达式1) { 语句体1; }else if(比较表达式2) { 语句体2; }else if(比较表达式3) { 语句体3; }... ... }else if(比较表达式n) { 语句体n; } else { 语句体n+1; } 执行流程: 判断比较表达式1的值,看是true还是false。 如果是true,就执行语句体1。 如果是false,就继续判断比较表达式2的值,看是true还是false。 如果是true,就执行语句体2。 如果是false,就继续判断比较表达式3的值,看是true还是false。 ... ... 如果都不满足,就执行语句体n+1。--------------------------------------- (2)注意事项: A:比较表达式无论是简单还是复杂,结果必须是boolean类型。 B:if语句控制的语句体如果是一条语句,是可以省略大括号的;如果是多条语句,则不能省略。 建议:永远不要省略。 C:一般来说:有左大括号就没有分号,有分号就没有左大括号。如下图所示13: D:else后面如果没有if,是不会出现比较表达式的。 E:三种格式的if语句其实都是一个语句,只要有一个语句体执行,其他的语句体就不再执行。--------------------------------------- (3)案例: A:比较两个数是否相等。 B:获取两个数中的最大值。 C:获取三个数中的最大值(if语句的嵌套)。 D:根据成绩输出对应的等级。 E:根据月份,输出对应的季节。 F:根据x计算对应y的值并输出。如下图所示14: (4)三元运算符和if语句第二种格式的关系: 所有的三元运算符能够实现的,if语句的第二种格式都能实现。 反之不成立。 如果if语句第二种格式控制的语句体是输出语句,就不可以。 因为三元运算符是一个运算符,必须要求有一个结果返回。不能是一个输出语句。=============================================================================我的GitHub地址: https://github.com/heizemingjun 我的博客园地址: http://www.cnblogs.com/chenmingjun 我的蚂蚁笔记博客地址: http://blog.leanote.com/chenmingjun Copyright ©2018 黑泽明军 【转载文章务必保留出处和署名,谢谢!】

优秀的个人博客,低调大师

Python学习笔记:lambda表达式与函数式编程

1,lambda的一般形式是关键字lambda后面跟一个或多个参数,紧跟一个冒号,以后是一个表达式。lambda是一个表达式而不是一个语句。它能够出现在Python语法不允许def出现的地方。作为表达式,lambda返回一个值(即一个新的函数)。lambda用来编写简单的函数,而def用来处理更强大的任务。 [python] view plain copy f=lambdax,y,z:x+y+z printf(1,2,3) g=lambdax,y=2,z=3:x+y+z printg(1,z=4,y=5) 输出结果为: [python] view plain copy 6 10 2,lambda表达式常用来编写跳转表(jump table),就是行为的列表或字典。例如: [python] view plain copy L=[(lambdax:x**2), (lambdax:x**3), (lambdax:x**4)] printL[0](2),L[1](2),L[2](2) D={'f1':(lambda:2+3), 'f2':(lambda:2*3), 'f3':(lambda:2**3)} printD['f1'](),D['f2'](),D['f3']() 输出结果为: [python] view plain copy 4816 568 3,lambda表达式可以嵌套使用,但是从可读性的角度来说,应尽量避免使用嵌套的lambda表达式。 4,map函数可以在序列中映射函数进行操作。例如: [python] view plain copy definc(x): returnx+10 L=[1,2,3,4] printmap(inc,L) printmap((lambdax:x+10),L) 输出结果为: [python] view plain copy [11,12,13,14] [11,12,13,14] 5,列表解析可以实现map函数同样的功能,而且往往比map要快。例如: [python] view plain copy print[x**2forxinrange(10)] printmap((lambdax:x**2),range(10)) 输出结果为: [python] view plain copy [0,1,4,9,16,25,36,49,64,81] [0,1,4,9,16,25,36,49,64,81] 6,列表解析比map更强大。例如: [python] view plain copy print[x+yforxinrange(5)ifx%2==0foryinrange(10)ify%2==1] 输出结果为: [python] view plain copy [1,3,5,7,9,3,5,7,9,11,5,7,9,11,13] 7,生成器函数就像一般的函数,但它们被用作实现迭代协议,因此生成器函数只能在迭代语境中出现。例如: [python] view plain copy defgensquares(N): foriinrange(N): yieldi**2 foriingensquares(5): printi, 输出结果为: [python] view plain copy 014916 8,所有的迭代内容(包括for循环、map调用、列表解析等等)将会自动调用iter函数,来看看是不是支持了迭代协议。 9,生成器表达式就像列表解析一样,但它们是扩在圆括号()中而不是方括号[]中。例如: [python] view plain copy fornumin(x**2forxinrange(5)): printnum, 输出结果为: [python] view plain copy 014916 10,列表解析比for循环具有更好的性能。尽管如此,在编写Python代码时,性能不应该是最优先考虑的。 11,没有return语句时,函数将返回None对象。 12,函数设计的概念: 耦合性:只有在真正必要的情况下才使用全局变量 耦合性:不要改变可变类型的参数,除非调用者希望这样做 耦合性:避免直接改变另一个文件模块中的变量 聚合性:每一个函数都应有一个单一的、统一的目标 13,最后给个默认参数和可变参数的例子: [python] view plain copy defsaver(x=[]): x.append(1) printx saver([2]) saver() saver() saver() 输出结果为: [python] view plain copy [2,1] [1] [1,1] [1,1,1] 原文地址http://www.bieryun.com/748.html

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册