Java面向对象理解_代码块_继承_多态_抽象_接口

面线对象:

/*
成员变量和局部变量的区别?
A:在类中的位置不同
成员变量:在类中方法外
局部变量:在方法定义中或者方法声明上
B:在内存中的位置不同
成员变量:在堆内存
局部变量:在栈内存
C:生命周期不同
成员变量:随着对象的创建而存在,随着对象的消失而消失
局部变量:随着方法的调用而存在,随着方法的调用完毕而消失
D:初始化值不同
成员变量:有默认初始化值
局部变量:没有默认初始化值,必须定义,赋值,然后才能使用。
 
注意事项:
局部变量名称可以和成员变量名称一样,在方法中使用的时候,采用的是就近原则。
*/
class Varialbe {
//成员变量
//int num = 10;
int num; //0
 
public void show() {
//int num2 = 20; //局部变量
//可能尚未初始化变量num2
//int num2; //没有默认值
int num2 = 20;
System.out.println(num2);
 
//int num = 100;
System.out.println(num);
}
}
 
 
class VariableDemo {
public static void main(String[] args) {
Varialbe v = new Varialbe();
 
System.out.println(v.num); //访问成员变量
 
v.show();
 
}
}
===================================================================
/*
形式参数的问题:
基本类型:形式参数的改变不影响实际参数
引用类型:形式参数的改变直接影响实际参数
*/
//形式参数是基本类型
class Demo {
public int sum(int a,int b) {
return a + b;
}
}
 
//形式参数是引用类型
class Student {
public void show() {
System.out.println("我爱学习");
}
}
 
class StudentDemo {
//如果你看到了一个方法的形式参数是一个类类型(引用类型),这里其实需要的是该类的对象。
public void method(Student s) { //调用的时候,把main方法中的s的地址传递到了这里 Student s = new Student();
s.show();
}
}
 
class ArgsTest {
public static void main(String[] args) {
//形式参数是基本类型的调用
Demo d = new Demo();
int result = d.sum(10,20);
System.out.println("result:"+result);
System.out.println("--------------");
 
//形式参数是引用类型的调用
//需求:我要调用StudentDemo类中的method()方法
StudentDemo sd = new StudentDemo();
//创建学生对象
Student s = new Student();
sd.method(s); //把s的地址给到了这里
}
}
==================================================
/*
匿名对象:就是没有名字的对象。
 
匿名对象的应用场景:
A:调用方法,仅仅只调用一次的时候。
注意:调用多次的时候,不适合。
那么,这种匿名调用有什么好处吗?
有,匿名对象调用完毕就是垃圾。可以被垃圾回收器回收。
B:匿名对象可以作为实际参数传递
*/
class Student {
public void show() {
System.out.println("我爱学习");
}
}
 
class StudentDemo {
public void method(Student s) {
s.show();
}
}
 
class NoNameDemo {
public static void main(String[] args) {
//带名字的调用
Student s = new Student();
s.show();
s.show();
System.out.println("--------------");
 
//匿名对象
//new Student();
//匿名对象调用方法
new Student().show();
new Student().show(); //这里其实是重新创建了一个新的对象
System.out.println("--------------");
 
 
//匿名对象作为实际参数传递
StudentDemo sd = new StudentDemo();
//Student ss = new Student();
//sd.method(ss); //这里的s是一个实际参数
//匿名对象
sd.method(new Student());
 
//在来一个
new StudentDemo().method(new Student());
}
}
====================================================================/*
private:
是一个权限修饰符
可以修饰成员变量和成员方法
被其修饰的成员只能在本类中被访问
*/
class Demo {
//int num = 10;
//用private修饰
private int num = 10;
 
public void show() {
System.out.println(num);
}
 
private void method() {
System.out.println("method");
}
 
public void function() {
method();
}
}
 
class PrivateDemo {
public static void main(String[] args) {
Demo d = new Demo();
//不能方法私有的成员变量
//System.out.println(d.num);
d.show();
//不能访问私有的成员方法
//d.method();
d.function();
}
}
 
============================================================
/*
定义一个学生类:
成员变量:name,age
成员方法:show()方法
 
我们在使用这个案例的过程中,发现了一个问题:
通过对象去给成员变量赋值,可以赋值一些非法的数据。
这是不合理的。
应该是这个样子的:在赋值之前,先对数据进行判断。
判断到底在哪里做比较合适呢?
StudentDemo类是一个测试类,测试类一般只创建对象,调用方法。
所以,这个判断应该定义在Student类中。
而我们在成员变量的位置可不可以进行数据判断呢?
是不可以的,因为做数据校验,必须要依靠一些逻辑语句。
逻辑语句是应该定义在方法中的,所以,我们最终决定在Student类中提供一个方法
来对数据进行校验。
 
按照我们前面的分析,我们给出了一个方法进行校验。
但是呢,它偏偏不调用方法来赋值,还是直接赋值了,
这样我们的方法就没有起到作用。
我就应该要求你必须使用我的方法,而不能直接调用成员变量赋值。
怎么去强制要求不能直接使用成员变量呢?
针对这种情况,Java就提供了一个关键字 private
 
private:私有的。可以修饰成员变量和成员方法。
注意:被private修饰的成员只能在本类中访问。
 
其实我讲到现在讲解的是一个封装的思想。
封装:是指隐藏对象的属性和实现细节,仅对外提供公共访问方式。
*/
class Student {
//姓名
String name;
//年龄
private int age;
 
//写一个方法对数据进行校验
/*
返回值类型:void
参数列表:int a
*/
public void setAge(int a) {
if(a < 0 || age > 120) {
System.out.println("你给的年龄有问题");
}else {
age = a;
}
}
 
 
//show()方法,显示所有成员变量值
public void show() {
System.out.println("姓名:"+name);
System.out.println("年龄:"+age);
}
}
 
class StudentDemo {
public static void main(String[] args) {
//创建学生对象
Student s = new Student();
s.show();
System.out.println("--------------");
 
//给成员变量赋值
s.name = "林青霞";
//s.age = 27;
s.setAge(27);
s.show();
System.out.println("--------------");
 
//给age赋值
//s.age = -27; //这个数据是不合理的
//通过方法给值
s.setAge(-27);
s.show();
System.out.println("--------------");
}
}
====================================================================/*
封装和private的应用:
A:把成员变量用private修饰
B:提高对应的getXxx()和setXxx()方法
*/
//定义学生类
class Student {
//姓名
private String name;
//年龄
private int age;
 
//姓名获取值
public String getName() {
return name;
}
 
//姓名设置值
public void setName(String n) {
name = n;
}
 
//年龄获取值
public int getAge() {
return age;
}
 
//年龄赋值
public void setAge(int a) {
age = a;
}
}
 
//测试类
class StudentTest {
public static void main(String[] args) {
//创建学生对象
Student s = new Student();
 
//使用成员变量
//错误:被私有修饰了,外界不能直接访问了
//System.out.println(s.name+"---"+s.age);
System.out.println(s.getName()+"---"+s.getAge());
 
//给成员变量赋值
//s.name = "林青霞";
//s.age = 27;
//通过方法给赋值
s.setName("林青霞");
s.setAge(27);
System.out.println(s.getName()+"---"+s.getAge());
}
}
======================================================
/*
作业:请把手机类写成一个标准类,然后创建对象测试功能。
 
手机类:
成员变量:
品牌:String brand;
价格:int price;
颜色:String color;
成员方法:
针对每一个成员变量给出对应的getXxx()/setXxx()方法。
最后定义测试:
创建一个对象,先通过getXxx()方法输出成员变量的值。这一次的结果是:null---0---null
然后通过setXxx()方法给成员变量赋值。再次输出结果。这一次的结果是:三星---2999---土豪金
*/
class Phone {
//品牌
private String brand;
//价格
private int price;
//颜色
private String color;
 
//getXxx()和setXxx()方法
public String getBrand() {
return brand;
}
 
public void setBrand(String brand) {
this.brand = brand;
}
 
public int getPrice() {
return price;
}
 
public void setPrice(int price) {
this.price = price;
}
 
public String getColor() {
return color;
}
 
public void setColor(String color) {
this.color = color;
}
}
 
class PhoneTest {
public static void main(String[] args) {
//创建手机对象
Phone p = new Phone();
 
//直接输出默认值
System.out.println(p.getBrand()+"---"+p.getPrice()+"---"+p.getColor());
 
//给成员变量赋值
p.setBrand("三星");
p.setPrice(2999);
p.setColor("土豪金");
//再次输出
System.out.println(p.getBrand()+"---"+p.getPrice()+"---"+p.getColor());
}
}
===========================================================
/*
我们曾经曰:起名字要做到见名知意。
 
this:是当前类的对象引用。简单的记,它就代表当前类的一个对象。
 
注意:谁调用这个方法,在该方法内部的this就代表谁。
 
this的场景:
解决局部变量隐藏成员变量
*/
//定义学生类
class Student {
//姓名
private String name;
//年龄
private int age;
 
//姓名获取值
public String getName() {
return name;
}
 
//姓名设置值
public void setName(String name) { //name = "林青霞";
//name = name; //变量的使用规则:就近原则
//这里是类名,目前还没有说过类似的用法,所以这个是有问题的
//这里的调用只能通过对象名
//这个对象如果存在,它应该代表的是Student的一个对象。
//那么,谁能够代表当前类的对象呢? java就提供了一个关键字 this
//Student.name = name;
this.name = name;
}
 
//年龄获取值
public int getAge() {
return age;
}
 
//年龄赋值
public void setAge(int age) {
this.age = age;
}
}
 
//测试类
class StudentTest {
public static void main(String[] args) {
//创建学生对象
Student s = new Student();
 
//给成员变量赋值
s.setName("林青霞");
s.setAge(27);
//获取数据
System.out.println(s.getName()+"---"+s.getAge());
}
}
============================
/*
标准的代码改进版
 
this:哪个对象调用那个方法,this就代表那个对象
*/
class Student {
private String name;
private int age;
 
public String getName() {
return name; //这里其实是隐含了this
}
 
public void setName(String name) {
this.name = name;
}
 
public int getAge() {
return age;
}
 
public void setAge(int age) {
this.age = age;
}
}
 
class StudentTest2 {
public static void main(String[] args) {
 
//创建一个对象
Student s1 = new Student();
s1.setName("林青霞");
s1.setAge(27);
System.out.println(s1.getName()+"---"+s1.getAge());
 
//创建第二个对象
Student s2 = new Student();
s2.setName("刘意");
s2.setAge(30);
System.out.println(s2.getName()+"---"+s2.getAge());
}
}
=============================================================
/*
构造方法:
给对象的数据进行初始化
 
格式:
A:方法名与类名相同
B:没有返回值类型,连void都没有
C:没有具体的返回值
*/
class Student {
private String name; //null
private int age; //0
 
public Student() {
System.out.println("这是构造方法");
}
}
 
class ConstructDemo {
public static void main(String[] args) {
//创建对象
Student s = new Student();
System.out.println(s); //Student@e5bbd6
}
}
=========================================================
/*
我们一直在使用构造方法,但是,我们确没有定义构造方法,用的是哪里来的呢?
 
构造方法的注意事项:
A:如果我们没有给出构造方法,系统将自动提供一个无参构造方法。
B:如果我们给出了构造方法,系统将不再提供默认的无参构造方法。
注意:这个时候,如果我们还想使用无参构造方法,就必须自己给出。建议永远自己给出无参构造方法
 
给成员变量赋值有两种方式:
A:setXxx()
B:构造方法
*/
 
class Student {
private String name;
private int age;
 
public Student() {
//System.out.println("我给了,你还给不");
System.out.println("这是无参构造方法");
}
 
//构造方法的重载格式
public Student(String name) {
System.out.println("这是带一个String类型的构造方法");
this.name = name;
}
 
public Student(int age) {
System.out.println("这是带一个int类型的构造方法");
this.age = age;
}
 
public Student(String name,int age) {
System.out.println("这是一个带多个参数的构造方法");
this.name = name;
this.age = age;
}
 
public void show() {
System.out.println(name+"---"+age);
}
}
 
class ConstructDemo2 {
public static void main(String[] args) {
//创建对象
Student s = new Student();
s.show();
System.out.println("-------------");
 
//创建对象2
Student s2 = new Student("林青霞");
s2.show();
System.out.println("-------------");
 
//创建对象3
Student s3 = new Student(27);
s3.show();
System.out.println("-------------");
 
//创建对象4
Student s4 = new Student("林青霞",27);
s4.show();
}
}
==================================================================
/*
类的组成:成员变量,成员方法
今天我们又加入了一个新的成员:构造方法。
以后再提类的组成:
成员变量
构造方法
成员方法
根据返回值:
void类型
非void类型
形式参数:
空参方法
非空参方法
*/
class Student {
public String getString() {
return "helloworld";
}
 
public void show() {
System.out.println("show");
}
 
public void method(String name) {
System.out.println(name);
}
 
public String function(String s1,String s2) {
return s1+s2;
}
}
 
class StudentDemo {
public static void main(String[] args) {
//创建对象
Student s = new Student();
 
//调用无参无返回值方法
s.show();
 
//调用无参有返回值方法
String result = s.getString();
System.out.println(result);
 
//调用带参无返回值的方法
s.method("林青霞");
 
//调用带参带返回值的方法
String result2 = s.function("hello","world");
System.out.println(result2);
}
}
=============================================================
/*
一个标准代码的最终版。
 
学生类:
成员变量:
name,age
构造方法:
无参,带两个参
成员方法:
getXxx()/setXxx()
show():输出该类的所有成员变量值
 
给成员变量赋值:
A:setXxx()方法
B:构造方法
 
输出成员变量值的方式:
A:通过getXxx()分别获取然后拼接
B:通过调用show()方法搞定
*/
class Student {
//姓名
private String name;
//年龄
private int age;
 
//构造方法
public Student() {
}
 
public Student(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 void show() {
System.out.println(name+"---"+age);
}
}
 
//测试类
class StudentTest {
public static void main(String[] args) {
//方式1给成员变量赋值
//无参构造+setXxx()
Student s1 = new Student();
s1.setName("林青霞");
s1.setAge(27);
//输出值
System.out.println(s1.getName()+"---"+s1.getAge());
s1.show();
System.out.println("----------------------------");
 
//方式2给成员变量赋值
Student s2 = new Student("刘意",30);
System.out.println(s2.getName()+"---"+s2.getAge());
s2.show();
}
}
====================================================================/*
需求:
定义一个员工类,自己分析出几个成员,
然后给出成员变量,构造方法,getXxx()/setXxx()方法,
以及一个显示所有成员信息的方法。并测试。
 
分析:
员工
成员变量:
员工编号,姓名,年龄
构造方法:
无参构造方法
成员方法:
getXxx()/setXxx()
show();
*/
class Employee {
//员工编号
private String employeeId;
//姓名
private String name;
//年龄
private int age;
 
//构造方法
public Employee() {}
 
//getXxx()/setXxx()
public String getEmployeeId() {
return employeeId;
}
 
public void setEmployeeId(String employeeId) {
this.employeeId = employeeId;
}
 
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 show() {
System.out.println("员工编号是:"+employeeId+"的这个人是:"+name+"的年龄是:"+age);
}
}
 
class EmployeeTest {
public static void main(String[] args) {
//创建对象
Employee e = new Employee();
 
//给成员变量赋值
e.setEmployeeId("czbk9527");
e.setName("唐伯虎");
e.setAge(18);
 
//获取数据
//System.out.println(e.getEmployeeId()+"---"+e.getName()+"---"+e.getAge());
 
//我们在Employee类中定义了一个show方法。所以,我们改进一下,使用show方法
e.show();
}
}
 
===================================================================
/*
定义一个类MyMath,提供基本的加减乘除功能,然后进行测试。
*/
import java.util.Scanner;
 
class MyMath {
//加法功能
public int add(int a,int b) {
return a + b;
}
 
//减法功能
public int sub(int a,int b) {
return a - b;
}
 
//乘法功能
public int mul(int a,int b){
return a * b;
}
 
//除法功能
public int div(int a,int b) {
return a / b;
}
}
 
//测试类
class MyMathTest {
public static void main(String[] args) {
//创建键盘录入对象
Scanner sc = new Scanner(System.in);
 
System.out.println("请输入第一个操作数:");
int firstNumber = sc.nextInt();
System.out.println("请输入第二个操作数:");
int secondNumber = sc.nextInt();
 
//创建MyMath对象,并使用
MyMath mm = new MyMath();
 
System.out.println("加法结果:"+mm.add(firstNumber,secondNumber));
System.out.println("减法结果:"+mm.sub(firstNumber,secondNumber));
System.out.println("乘法结果:"+mm.mul(firstNumber,secondNumber));
System.out.println("除法结果:"+mm.div(firstNumber,secondNumber));
}
}
 
 
==================================================================
/*
定义一个类Demo,其中定义一个求两个数据和的方法,
定义一个测试了Test,进行测试。
 
变量什么时候定义为成员变量:
如果这个变量是用来描述这个类的信息的,那么,该变量就应该定义为成员变量。
 
变量到底定义在哪里好呢?
变量的范围是越小越好。因为能及时的被回收。
*/
 
//方式1
/*
class Demo {
public int sum() {
int a = 10;
int b = 20;
int c = a + b;
return c;
}
}
*/
//方式1满足了我们的要求,但是不好。
//因为参与操作的数据现在是固定的。
 
//方式2
/*
class Demo {
public int sum(int a,int b) {
return a + b;
}
}
*/
 
//方式2可以满足我们的要求,但是呢我们学习过来面向对象的思想。
//我就再想,a,b可不可以定义为成员变量呢?
//如果可以,我们再改进一版
class Demo {
int a;
int b;
 
public int sum() {
return a + b;
}
}
//虽然这种方式可以,并且好像是符合了面向对象的思想。
//但是不好。
//因为我们曾经说过:类是一组相关的属性和行为的集合。
//并且类是通过事物转换过来的
//而类中的成员变量就是事物的属性
//属性是用来描述事物的
//同理:成员变量其实是用来描述类的。
 
//测试类
class Test {
public static void main(String[] args) {
//创建对象
//方式1测试
/*
Demo d = new Demo();
System.out.println(d.sum());
*/
 
//方式2测试
/*
Demo d = new Demo();
int a = 10;
int b = 20;
System.out.println(d.sum(a,b));
*/
 
//方式3测试
Demo d = new Demo();
d.a = 10;
d.b = 20;
System.out.println(d.sum());
}
}
=============================================
/*
定义一个长方形类,定义 求周长和面积的方法,
然后定义一个测试了Test2,进行测试。
 
长方形的类:
成员变量:
长,宽
成员方法:
求周长:(长+宽)*2;
求面积:长*宽
 
注意:
import必须出现在所有的class前面。
*/
 
import java.util.Scanner;
 
class ChangFangXing {
//长方形的长
private int length;
//长方形的宽
private int width;
 
public ChangFangXing(){}
 
//仅仅提供setXxx()即可
public void setLength(int length) {
this.length = length;
}
 
public void setWidth(int width) {
this.width = width;
}
 
//求周长
public int getZhouChang() {
return (length + width) * 2;
}
 
//求面积
public int getArea() {
return length * width;
}
}
 
class Test2 {
public static void main(String[] args) {
//创建键盘录入对象
Scanner sc = new Scanner(System.in);
 
System.out.println("请输入长方形的长:");
int length = sc.nextInt();
System.out.println("请输入长方形的宽:");
int width = sc.nextInt();
 
//创建对象
ChangFangXing cfx = new ChangFangXing();
//先给成员变量赋值
cfx.setLength(length);
cfx.setWidth(width);
 
System.out.println("周长是:"+cfx.getZhouChang());
System.out.println("面积是:"+cfx.getArea());
}
}
==============================================================================
/*
main方法的格式讲解:
public static void main(String[] args) {...}
 
public:公共的,访问权限是最大的。由于main方法是被jvm调用,所以权限要够大。
static:静态的,不需要创建对象,通过类名就可以。方便jvm的调用。
void:因为我们曾经说过,方法的返回值是返回给调用者,而main方法是被jvm调用。你返回内容给jvm没有意义。
main:是一个常见的方法入口。我见过的语言都是以main作为入口。
String[] args:这是一个字符串数组。值去哪里了?
这个东西到底有什么用啊?怎么给值啊?
这个东西早期是为了接收键盘录入的数据的。
格式是:
java MainDemo hello world java
*/
class MainDemo {
public static void main(String[] args) {
//System.out.println(args); //[Ljava.lang.String;@175078b
//System.out.println(args.length); //0
//System.out.println(args[0]); //ArrayIndexOutOfBoundsException
 
//接收数据后
System.out.println(args);
System.out.println(args.length);
//System.out.println(args[0]);
for(int x=0; x<args.length; x++) {
System.out.println(args[x]);
}
}
}
 
===================================
/*
定义一个人类
 
姓名和年龄都是变化的,这个我能接收,因为每个人的姓名和年龄是不同的。
但是,我们现在选取的几个人都是中国人,他们的国籍是一样的。
一样的国籍,我每次创建对象,在堆内存都要开辟这样的空间,
我就觉得有点浪费了。怎么办呢?
针对多个对象有共同的这样的成员变量值的时候,
Java就提高了一个关键字来修饰:static。
*/
class Person {
//姓名
String name;
//年龄
int age;
//国籍
//String country;
static String country;
 
public Person(){}
 
public Person(String name,int age) {
this.name = name;
this.age = age;
}
 
public Person(String name,int age,String country) {
this.name = name;
this.age = age;
this.country = country;
}
 
public void show() {
System.out.println("姓名:"+name+",年龄:"+age+",国籍:"+country);
}
}
 
class PersonDemo {
public static void main(String[] args) {
//创建对象1
Person p1 = new Person("邓丽君",16,"中国");
p1.show();
 
//创建对象2
//Person p2 = new Person("杨幂",22,"中国");
//p2.show();
Person p2 = new Person("杨幂",22);
p2.show();
 
//创建对象3
//Person p3 = new Person("凤姐",20,"中国");
//p3.show();
Person p3 = new Person("凤姐",20);
p3.show();
 
p3.country = "美国";
p3.show();
 
p1.show();
p2.show();
 
/*
姓名:邓丽君,年龄:16,国籍:中国
姓名:杨幂,年龄:22,国籍:中国
姓名:凤姐,年龄:20,国籍:中国
姓名:凤姐,年龄:20,国籍:美国
姓名:邓丽君,年龄:16,国籍:美国
姓名:杨幂,年龄:22,国籍:美国
/*
}
}
====================================================================/*
static的特点:(它可以修饰成员变量,还可以修饰成员方法)
A:随着类的加载而加载
回想main方法。
B:优先于对象存在
C:被类的所有对象共享
举例:咱们班级的学生应该共用同一个班级编号。
其实这个特点也是在告诉我们什么时候使用静态?
如果某个成员变量是被所有对象共享的,那么它就应该定义为静态的。
举例:
饮水机(用静态修饰)
水杯(不能用静态修饰)
D:可以通过类名调用
其实它本身也可以通过对象名调用。
推荐使用类名调用。
 
静态修饰的内容一般我们称其为:与类相关的,类成员
*/
class Student {
//非静态变量
int num = 10;
 
//静态变量
static int num2 = 20;
}
 
class StudentDemo {
public static void main(String[] args) {
Student s = new Student();
System.out.println(s.num);
 
System.out.println(Student.num2);
System.out.println(s.num2);
}
}
===========================================================
/*
static关键字注意事项
A:在静态方法中是没有this关键字的
如何理解呢?
静态是随着类的加载而加载,this是随着对象的创建而存在。
静态比对象先存在。
B:静态方法只能访问静态的成员变量和静态的成员方法
静态方法:
成员变量:只能访问静态变量
成员方法:只能访问静态成员方法
非静态方法:
成员变量:可以是静态的,也可以是非静态的
成员方法:可是是静态的成员方法,也可以是非静态的成员方法。
简单记:
静态只能访问静态。
*/
class Teacher {
public int num = 10;
public static int num2 = 20;
 
public void show() {
System.out.println(num); //隐含的告诉你访问的是成员变量
System.out.println(this.num); //明确的告诉你访问的是成员变量
System.out.println(num2);
 
//function();
//function2();
}
 
public static void method() {
//无法从静态上下文中引用非静态 变量 num
//System.out.println(num);
System.out.println(num2);
 
//无法从静态上下文中引用非静态 方法 function()
//function();
function2();
}
 
public void function() {
 
}
 
public static void function2() {
 
}
}
 
class TeacherDemo {
public static void main(String[] args) {
//创建对象
Teacher t = new Teacher();
t.show();
System.out.println("------------");
t.method();
}
}
 
二.代码块和继承
/*
我想要对数组进行操作
 
在同一个文件夹下,类定义在两个文件中和定义在一个文件中其实一样的。
*/
class ArrayDemo {
public static void main(String[] args) {
//定义数组
int[] arr = {28,55,37,46,19};
 
//需求:遍历数组
/*
for(int x=0; x<arr.length; x++) {
if(x == arr.length-1) {
System.out.println(arr[x]);
}else {
System.out.print(arr[x]+", ");
}
}
*/
 
//如果我有多个数组都要进行遍历,那么,代码的重复度就很高
//如何改进呢?用方法改进
//调用
//静态方法
//printArray(arr);
 
//非静态方法
//ArrayDemo ad = new ArrayDemo();
//ad.printArray(arr);
 
//测试类的作用:创建其他类的对象,调用其他类的功能。
//而我们现在的操作是跟数组相关的,所以,你应该把这些操作定义到数组操作类中
//定义一个数组的操作类
//有了数组操作类之后的调用
//ArrayTool at = new ArrayTool();
//at.printArray(arr);
 
//方法改进为静态后,就可以直接通过类名调用
ArrayTool.printArray(arr);
}
 
/*
public static void printArray(int[] arr) {
for(int x=0; x<arr.length; x++) {
if(x == arr.length-1) {
System.out.println(arr[x]);
}else {
System.out.print(arr[x]+", ");
}
}
}
*/
 
//假设该方法不是静态的
/*
public void printArray(int[] arr) {
for(int x=0; x<arr.length; x++) {
if(x == arr.length-1) {
System.out.println(arr[x]);
}else {
System.out.print(arr[x]+", ");
}
}
}
*/
}
======================================
class ArrayTool {
 
//把构造方法私有,外界就不能在创建对象了
private ArrayTool(){}
 
public static void printArray(int[] arr) {
for(int x=0; x<arr.length; x++) {
if(x == arr.length-1) {
System.out.println(arr[x]);
}else {
System.out.print(arr[x]+", ");
}
}
}
}
==============================
/*
我想要对数组进行操作
 
如何制作一个说明书呢?
A:写一个工具类
B:对这个类加入文档注释
怎么加呢?
加些什么东西呢?
C:用工具解析文档注释
javadoc工具
D:格式
javadoc -d 目录 -author -version ArrayTool.java
 
目录:就可以写一个文件夹的路径
 
制作帮助文档出错:
找不到可以文档化的公共或受保护的类:告诉我们类的权限不够
*/
class ArrayDemo {
public static void main(String[] args) {
//定义数组
int[] arr = {28,55,37,46,19};
 
//遍历
ArrayTool.printArray(arr);
 
//获取最值
int max = ArrayTool.getMax(arr);
System.out.println("max:"+max);
 
//获取55的索引值
int index = ArrayTool.getIndex(arr,55);
System.out.println("index:"+index);
}
}
=============================================
/**
* 这是针对数组进行操作的工具类
* @author 刘意
* @version V.10
*/
public class ArrayTool {
 
//把构造方法私有,外界就不能在创建对象了
/**
* 这是私有构造
*/
private ArrayTool(){}
 
/**
* 这是遍历数组的方法,遍历后的格式是:[元素1, 元素2, 元素3, ...]
* @param arr 这是要被遍历的数组
*/
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]+", ");
}
}
}
 
/**
* 这是获取数组中最大值的方法
* @param arr 这是要获取最大值的数组
* @return 返回数组中的最大值
*/
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;
}
 
/**
* 获取指定元素在数组中第一次出现的索引,如果元素不存在,就返回-1
* @param arr 被查找的数组
* @param value 要查找的元素
* @return 返回元素在数组中的索引,如果不存在,返回-1
*/
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;
}
}
====================================
/*
猜数字小游戏(数据在1-100之间)
 
分析:
A:程序产生一个随机数。(被猜的)
B:键盘录入数据。(你猜的)
C:把你猜的和被猜的进行比较
a:大了
b:小了
c:猜中了
D:给出多次猜的机会,猜中就结束。
while()循环,猜中就break
*/
import java.util.Scanner;
 
class GuessNumber {
public static void main(String[] args) {
//程序产生一个随机数。(被猜的)
int number = (int)(Math.random()*100)+1;
//System.out.println(number);
 
//给出多次猜的机会,猜中就结束。
while(true) {
//键盘录入数据。(你猜的)
Scanner sc = new Scanner(System.in);
System.out.println("请输入你要猜的数据(1-100):");
int guessNumber = sc.nextInt();
 
//把你猜的和被猜的进行比较
if(guessNumber > number) {
System.out.println("你猜的数据"+guessNumber+"大了");
}else if(guessNumber < number) {
System.out.println("你猜的数据"+guessNumber+"小了");
}else {
System.out.println("恭喜你,猜中了");
break;
}
}
}
}
=================================================
/*
Math:类包含用于执行基本数学运算的方法
 
由于Math类在java.lang包下,所以不需要导包。
特点:
没有构造方法,因为它的成员全部是静态的。
 
掌握一个方法:
获取随机数
public static double random():返回带正号的 double 值,该值大于等于 0.0 且小于 1.0。
*/
class MathDemo {
public static void main(String[] args) {
//获取一个随机数
//double d = Math.random();
//System.out.println(d);
 
//需求:我要获取一个1-100之间的随机数,肿么办?
for(int x=0; x<100; x++) {
int number = (int)(Math.random()*100)+1;
System.out.println(number);
}
}
}
==================================================================
1:打开帮助文档
2:点击显示,找到索引,看到输入框
3:知道你要找谁?以Scanner举例
4:在输入框里面输入Scanner,然后回车
5:看包
java.lang包下的类不需要导入,其他的全部需要导入。
 
要导入:
java.util.Scanner
6:再简单的看看类的解释和说明,别忘了看看该类的版本
7:看类的结构
成员变量 字段摘要
构造方法 构造方法摘要
成员方法 方法摘要
8:学习构造方法
A:有构造方法 就创建对象
B:没有构造方法 成员可能都是静态的
9:看成员方法
A:左边
是否静态:如果静态,可以通过类名调用
返回值类型:人家返回什么,你就用什么接收。
B:右边
看方法名:方法名称不要写错
参数列表:人家要什么,你就给什么;人家要几个,你就给几个
=========================
/*
代码块:在Java中,使用{}括起来的代码被称为代码块。
根据其位置和声明的不同,可以分为
局部代码块:局部位置,用于限定变量的生命周期。
构造代码块:在类中的成员位置,用{}括起来的代码。每次调用构造方法执行前,都会先执行构造代码块。
作用:可以把多个构造方法中的共同代码放到一起,对对象进行初始化。
静态代码块:在类中的成员位置,用{}括起来的代码,只不过它用static修饰了。
作用:一般是对类进行初始化。
 
面试题?
静态代码块,构造代码块,构造方法的执行顺序?
静态代码块 -- 构造代码块 -- 构造方法
静态代码块:只执行一次
构造代码块:每次调用构造方法都执行
*/
class Code {
static {
int a = 1000;
System.out.println(a);
}
 
//构造代码块
{
int x = 100;
System.out.println(x);
}
 
//构造方法
public Code(){
System.out.println("code");
}
 
//构造方法
public Code(int a){
System.out.println("code");
}
 
//构造代码块
{
int y = 200;
System.out.println(y);
}
 
//静态代码块
static {
int b = 2000;
System.out.println(b);
}
}
 
class CodeDemo {
public static void main(String[] args) {
//局部代码块
{
int x = 10;
System.out.println(x);
}
//找不到符号
//System.out.println(x);
{
int y = 20;
System.out.println(y);
}
System.out.println("---------------");
 
Code c = new Code();
System.out.println("---------------");
Code c2 = new Code();
System.out.println("---------------");
Code c3 = new Code(1);
}
}
=================================
/*
写程序的执行结果。
 
林青霞都60了,我很伤心
我是main方法
Student 静态代码块
Student 构造代码块
Student 构造方法
Student 构造代码块
Student 构造方法
*/
class Student {
static {
System.out.println("Student 静态代码块");
}
 
{
System.out.println("Student 构造代码块");
}
 
public Student() {
System.out.println("Student 构造方法");
}
}
 
class StudentDemo {
static {
System.out.println("林青霞都60了,我很伤心");
}
 
public static void main(String[] args) {
System.out.println("我是main方法");
 
Student s1 = new Student();
Student s2 = new Student();
}
}
====================================================================/*
继承概述:
把多个类中相同的内容给提取出来定义到一个类中。
 
如何实现继承呢?
Java提供了关键字:extends
 
格式:
class 子类名 extends 父类名 {}
 
好处:
A:提高了代码的复用性
B:提高了代码的维护性
C:让类与类之间产生了关系,是多态的前提
 
类与类产生了关系,其实也是继承的一个弊端:
类的耦合性增强了。
 
开发的原则:低耦合,高内聚。
耦合:类与类的关系
内聚:就是自己完成某件事情的能力
*/
 
//使用继承前
/*
class Student {
public void eat() {
System.out.println("吃饭");
}
 
public void sleep() {
System.out.println("睡觉");
}
}
 
class Teacher {
public void eat() {
System.out.println("吃饭");
}
 
public void sleep() {
System.out.println("睡觉");
}
}
*/
 
//使用继承后
class Person {
public void eat() {
System.out.println("吃饭");
}
 
public void sleep() {
System.out.println("睡觉");
}
}
 
class Student extends Person {}
 
class Teacher extends Person {}
 
class ExtendsDemo {
public static void main(String[] args) {
Student s = new Student();
s.eat();
s.sleep();
System.out.println("-------------");
 
Teacher t = new Teacher();
t.eat();
t.sleep();
}
}
====================================================
/*
Java中继承的特点:
A:Java只支持单继承,不支持多继承。
有些语言是支持多继承,格式:extends 类1,类2,...
B:Java支持多层继承(继承体系)
*/
 
/*
class Father {}
class Mother {}
class Son exnteds Father {} //正确的
class Son extends Father,Mother {} // 错误的
*/
 
class GrandFather {
public void show() {
System.out.println("我是爷爷");
}
}
 
class Father extends GrandFather {
public void method(){
System.out.println("我是老子");
}
}
 
class Son extends Father {}
 
class ExtendsDemo2 {
public static void main(String[] args) {
Son s = new Son();
s.method(); //使用父亲的
s.show(); //使用爷爷的
}
}
====================================================================/*
继承的注意事项:
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()不是你想要的。
 
那么,我们什么时候考虑使用继承呢?
继承其实体现的是一种关系:"is a"。
Person
Student
Teacher
水果
苹果
香蕉
橘子
 
采用假设法。
如果有两个类A,B。只有他们符合A是B的一种,或者B是A的一种,就可以考虑使用继承。
*/
class Father {
private int num = 10;
public int num2 = 20;
 
//私有方法,子类不能继承
private void method() {
System.out.println(num);
System.out.println(num2);
}
 
public void show() {
System.out.println(num);
System.out.println(num2);
}
}
 
class Son extends Father {
public void function() {
//num可以在Father中访问private
//System.out.println(num); //子类不能继承父类的私有成员变量
System.out.println(num2);
}
}
 
class ExtendsDemo3 {
public static void main(String[] args) {
// 创建对象
Son s = new Son();
//s.method(); //子类不能继承父类的私有成员方法
s.show();
s.function();
}
}
====================================================================/*
类的组成:
成员变量:
构造方法:
成员方法:
而现在我们又讲解了继承,所以,我们就应该来考虑一下,类的组成部分的各自关系。
 
继承中成员变量的关系:
A:子类中的成员变量和父类中的成员变量名称不一样,这个太简单。
B:子类中的成员变量和父类中的成员变量名称一样,这个怎么玩呢?
在子类方法中访问一个变量的查找顺序:
a: 在子类方法的局部范围找,有就使用
b:在子类的成员范围找,有就使用
c:在父类的成员范围找,有就使用
d:如果还找不到,就报错。
*/
class Father {
public int num = 10;
 
public void method() {
int num = 50;
}
}
 
class Son extends Father {
public int num2 = 20;
public int num = 30;
 
public void show() {
int num = 40;
System.out.println(num);
System.out.println(num2);
// 找不到符号
System.out.println(num3);
}
}
 
class ExtendsDemo4 {
public static void main(String[] args) {
//创建对象
Son s = new Son();
s.show();
}
}
====================================================================/*
问题是:
我不仅仅要输出局部范围的num,还要输出本类成员范围的num。怎么办呢?
我还想要输出父类成员范围的num。怎么办呢?
如果有一个东西和this相似,但是可以直接访问父类的数据就好了。
恭喜你,这个关键字是存在的:super。
 
this和super的区别?
分别是什么呢?
this代表本类对应的引用。
super代表父类存储空间的标识(可以理解为父类引用,可以操作父类的成员)
 
怎么用呢?
A:调用成员变量
this.成员变量 调用本类的成员变量
super.成员变量 调用父类的成员变量
B:调用构造方法
this(...) 调用本类的构造方法
super(...) 调用父类的构造方法
C:调用成员方法
this.成员方法 调用本类的成员方法
super.成员方法 调用父类的成员方法
*/
class Father {
public int num = 10;
}
 
class Son extends Father {
public int num = 20;
 
public void show() {
int num = 30;
System.out.println(num);
System.out.println(this.num);
System.out.println(super.num);
}
}
 
class ExtendsDemo5 {
public static void main(String[] args) {
Son s = new Son();
s.show();
}
}
====================================================================/*
继承中构造方法的关系
A:子类中所有的构造方法默认都会访问父类中空参数的构造方法
B:为什么呢?
因为子类会继承父类中的数据,可能还会使用父类的数据。
所以,子类初始化之前,一定要先完成父类数据的初始化。
 
注意:子类每一个构造方法的第一条语句默认都是:super();
*/
class Father {
int age;
 
public Father() {
System.out.println("Father的无参构造方法");
}
 
public Father(String name) {
System.out.println("Father的带参构造方法");
}
}
 
class Son extends Father {
public Son() {
//super();
System.out.println("Son的无参构造方法");
}
 
public Son(String name) {
//super();
System.out.println("Son的带参构造方法");
}
}
 
class ExtendsDemo6 {
public static void main(String[] args) {
//创建对象
Son s = new Son();
System.out.println("------------");
Son s2 = new Son("林青霞");
}
}
====================================================================/*
如果父类没有无参构造方法,那么子类的构造方法会出现什么现象呢?
报错。
如何解决呢?
A:在父类中加一个无参构造方法
B:通过使用super关键字去显示的调用父类的带参构造方法
C:子类通过this去调用本类的其他构造方法
子类中一定要有一个去访问了父类的构造方法,否则父类数据就没有初始化。
 
注意事项:
this(...)或者super(...)必须出现在第一条语句上。
如果不是放在第一条语句上,就可能对父类的数据进行了多次初始化,所以必须放在第一条语句上。
*/
class Father {
/*
public Father() {
System.out.println("Father的无参构造方法");
}
*/
 
public Father(String name) {
System.out.println("Father的带参构造方法");
}
}
 
class Son extends Father {
public Son() {
super("随便给");
System.out.println("Son的无参构造方法");
//super("随便给");
}
 
public Son(String name) {
//super("随便给");
this();
System.out.println("Son的带参构造方法");
}
}
 
class ExtendsDemo7 {
public static void main(String[] args) {
Son s = new Son();
System.out.println("----------------");
Son ss = new Son("林青霞");
}
}
==================================================
/*
继承中成员方法的关系:
A:子类中的方法和父类中的方法声明不一样,这个太简单。
B:子类中的方法和父类中的方法声明一样,这个该怎么玩呢?
通过子类对象调用方法:
a:先找子类中,看有没有这个方法,有就使用
b:再看父类中,有没有这个方法,有就使用
c:如果没有就报错。
*/
class Father {
public void show() {
System.out.println("show Father");
}
}
 
class Son extends Father {
public void method() {
System.out.println("method Son");
}
 
public void show() {
System.out.println("show Son");
}
}
 
class ExtendsDemo8 {
public static void main(String[] args) {
//创建对象
Son s = new Son();
s.show();
s.method();
//s.fucntion(); //找不到符号
}
}
============================================================
/*
方法重写:子类中出现了和父类中方法声明一模一样的方法。
 
方法重载:
本类中出现的方法名一样,参数列表不同的方法。与返回值无关。
 
子类对象调用方法的时候:
先找子类本身,再找父类。
 
方法重写的应用:
当子类需要父类的功能,而功能主体子类有自己特有内容时,可以重写父类中的方法。
这样,即沿袭了父类的功能,又定义了子类特有的内容。
 
案例:
A:定义一个手机类。
B:通过研究,我发明了一个新手机,这个手机的作用是在打完电话后,可以听天气预报。
按照我们基本的设计,我们把代码给写出来了。
但是呢?我们又发现新手机应该是手机,所以,它应该继承自手机。
其实这个时候的设计,并不是最好的。
因为手机打电话功能,是手机本身就具备的最基本的功能。
所以,我的新手机是不用在提供这个功能的。
但是,这个时候,打电话功能就没有了。这个不好。
最终,还是加上这个功能。由于它继承了手机类,所以,我们就直接使用父类的功能即可。
那么,如何使用父类的功能呢?通过super关键字调用
*/
class Phone {
public void call(String name) {
System.out.println("给"+name+"打电话");
}
}
 
class NewPhone extends Phone {
public void call(String name) {
//System.out.println("给"+name+"打电话");
super.call(name);
System.out.println("可以听天气预报了");
}
}
 
class ExtendsDemo9 {
public static void main(String[] args) {
NewPhone np = new NewPhone();
np.call("林青霞");
}
}
============================================================
/*
方法重写的注意事项
A:父类中私有方法不能被重写
因为父类私有方法子类根本就无法继承
B:子类重写父类方法时,访问权限不能更低
最好就一致
C:父类静态方法,子类也必须通过静态方法进行重写
其实这个算不上方法重写,但是现象确实如此,至于为什么算不上方法重写,多态中我会讲解
 
子类重写父类方法的时候,最好声明一模一样。
*/
class Father {
//private void show() {}
 
/*
public void show() {
System.out.println("show Father");
}
*/
 
void show() {
System.out.println("show Father");
}
/*
public static void method() {
 
}
*/
 
public void method() {
 
}
}
 
class Son extends Father {
//private void show() {}
 
/*
public void show() {
System.out.println("show Son");
}
*/
 
public void show() {
System.out.println("show Son");
}
 
 
public static void method() {
 
}
 
/*
public void method() {
 
}
*/
}
 
class ExtendsDemo10 {
public static void main(String[] args) {
Son s = new Son();
s.show();
}
}
 
================================================================
/*
看程序写结果:
A:成员变量 就近原则
B:this和super的问题
this访问本类的成员
super访问父类的成员
C:子类构造方法执行前默认先执行父类的无参构造方法
D:一个类的初始化过程
成员变量进行初始化
默认初始化
显示初始化
构造方法初始化
 
结果:
fu
zi
30
20
10
*/
class Fu{
public int num = 10;
public Fu(){
System.out.println("fu");
}
}
class Zi extends Fu{
public int num = 20;
public Zi(){
System.out.println("zi");
}
public void show(){
int num = 30;
System.out.println(num); //30
System.out.println(this.num); //20
System.out.println(super.num); //10
}
}
class ExtendsTest {
public static void main(String[] args) {
Zi z = new Zi();
z.show();
}
}
=====================================================
/*
看程序写结果:
A:一个类的静态代码块,构造代码块,构造方法的执行流程
静态代码块 > 构造代码块 > 构造方法
B:静态的内容是随着类的加载而加载
静态代码块的内容会优先执行
C:子类初始化之前先会进行父类的初始化
 
结果是:
静态代码块Fu
静态代码块Zi
构造代码块Fu
构造方法Fu
构造代码块Zi
构造方法Zi
*/
class Fu {
static {
System.out.println("静态代码块Fu");
}
 
{
System.out.println("构造代码块Fu");
}
 
public Fu() {
System.out.println("构造方法Fu");
}
}
 
class Zi extends Fu {
static {
System.out.println("静态代码块Zi");
}
 
{
System.out.println("构造代码块Zi");
}
 
public Zi() {
System.out.println("构造方法Zi");
}
}
 
class ExtendsTest2 {
public static void main(String[] args) {
Zi z = new Zi();
}
}
 
 
==========================================================
/*
学生案例和老师案例讲解
 
学生:
成员变量;姓名,年龄
构造方法:无参,带参
成员方法:getXxx()/setXxx()
老师:
成员变量;姓名,年龄
构造方法:无参,带参
成员方法:getXxx()/setXxx()
*/
//定义学生类
class Student {
//姓名
private String name;
//年龄
private int age;
 
public Student() {
}
 
public Student(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;
}
}
 
//定义老师类
class Teacher {
//姓名
private String name;
//年龄
private int age;
 
public Teacher() {
}
 
public Teacher(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;
}
}
 
class ExtendsTest3 {
public static void main(String[] args) {
//创建学生对象并测试
//方式1
Student s1 = new Student();
s1.setName("林青霞");
s1.setAge(27);
System.out.println(s1.getName()+"---"+s1.getAge());
 
//方式2
Student s2 = new Student("林青霞",27);
System.out.println(s2.getName()+"---"+s2.getAge());
 
//对应的老师测试我不想了,留给你们自己练习。
}
}
===================================================================
/*
学生案例和老师案例讲解
 
学生:
成员变量;姓名,年龄
构造方法:无参,带参
成员方法:getXxx()/setXxx()
老师:
成员变量;姓名,年龄
构造方法:无参,带参
成员方法:getXxx()/setXxx()
 
看上面两个类的成员,发现了很多相同的东西,所以我们就考虑抽取一个共性的类:
人:
成员变量;姓名,年龄
构造方法:无参,带参
成员方法:getXxx()/setXxx()
 
学生 继承 人
老师 继承 人
*/
//定义人类
class Person {
//姓名
private String name;
//年龄
private int age;
 
public Person() {
}
 
public Person(String name,int age) { //"林青霞",27
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;
}
}
 
//定义学生类
class Student extends Person {
public Student() {}
 
public Student(String name,int age) { //"林青霞",27
//this.name = name;
//this.age = age;
super(name,age);
}
}
 
//定义老师类
class Teacher extends Person {
 
}
 
class ExtendsTest4 {
public static void main(String[] args) {
//创建学生对象并测试
//方式1
Student s1 = new Student();
s1.setName("林青霞");
s1.setAge(27);
System.out.println(s1.getName()+"---"+s1.getAge());
 
//方式2
Student s2 = new Student("林青霞",27);
System.out.println(s2.getName()+"---"+s2.getAge());
 
//补齐老师类中的代码并进行测试。
}
}
====================================================================
/*
猫狗案例讲解
 
先找到具体的事物,然后发现具体的事物有共性,才提取出一个父类。
 
猫:
成员变量:姓名,年龄,颜色
构造方法:无参,带参
成员方法:
getXxx()/setXxx()
eat()
palyGame()
狗:
成员变量:姓名,年龄,颜色
构造方法:无参,带参
成员方法:
getXxx()/setXxx()
eat()
lookDoor()
 
共性:
成员变量:姓名,年龄,颜色
构造方法:无参,带参
成员方法:
getXxx()/setXxx()
eat()
 
把共性定义到一个类中,这个类的名字叫:动物。
动物类:
成员变量:姓名,年龄,颜色
构造方法:无参,带参
成员方法:
getXxx()/setXxx()
eat()
 
猫:
构造方法:无参,带参
成员方法:palyGame()
狗:
构造方法:无参,带参
成员方法:lookDoor()
*/
//定义动物类
class Animal {
//姓名
private String name;
//年龄
private int age;
//颜色
private String color;
 
public Animal() {}
 
public Animal(String name,int age,String color) {
this.name = name;
this.age = age;
this.color = color;
}
 
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 String getColor() {
return color;
}
 
public void setColor(String color) {
this.color = color;
}
 
public void eat() {
System.out.println("不要睡了,该吃饭了");
}
}
 
//定义猫类
class Cat extends Animal {
public Cat() {}
 
public Cat(String name,int age,String color) {
super(name,age,color);
}
 
public void playGame() {
System.out.println("猫玩英雄联盟");
}
}
 
//定义狗类
class Dog extends Animal {
public Dog() {}
 
public Dog(String name,int age,String color) {
super(name,age,color);
}
 
public void lookDoor() {
System.out.println("狗看家");
}
}
 
//测试类
class ExtendsTest5 {
public static void main(String[] args) {
//测试猫
//方式1
Cat c1 = new Cat();
c1.setName("Tom");
c1.setAge(3);
c1.setColor("白色");
System.out.println("猫的名字是:"+c1.getName()+";年龄是:"+c1.getAge()+";颜色是:"+c1.getColor());
c1.eat();
c1.playGame();
System.out.println("---------------");
 
//方式2
Cat c2 = new Cat("杰瑞",5,"土豪金");
System.out.println("猫的名字是:"+c2.getName()+";年龄是:"+c2.getAge()+";颜色是:"+c2.getColor());
c2.eat();
c2.playGame();
 
//作业:测试狗
}
}
 
==============================================================================================================================
/*
看程序写结果:
A:成员变量的问题
int x = 10; //成员变量是基本类型
Student s = new Student(); //成员变量是引用类型
B:一个类的初始化过程
成员变量的初始化
默认初始化
显示初始化
构造方法初始化
C:子父类的初始化(分层初始化)
先进行父类初始化,然后进行子类初始化。
 
结果:
YXYZ
 
问题:
虽然子类中构造方法默认有一个super()
初始化的时候,不是按照那个顺序进行的。
而是按照分层初始化进行的。
它仅仅表示要先初始化父类数据,再初始化子类数据。
*/
class X {
Y b = new Y();
X() {
System.out.print("X");
}
}
 
class Y {
Y() {
System.out.print("Y");
}
}
 
public class Z extends X {
Y y = new Y();
Z() {
//super
System.out.print("Z");
}
public static void main(String[] args) {
new Z();
}
}
========================
首先我来写两个代码:
//定义学生类
class Student {
String name;
int age;
 
public Student(){}
 
//getXxx()/setXxx()
 
public void eat() {
System.out.println("吃饭");
}
}
 
//定义老师类
class Teacher {
String name;
int age;
 
public Teacher(){}
 
//getXxx()/setXxx()
 
public void eat() {
System.out.println("吃饭");
}
}
我们观察上面两个代码:
发现name,age成员变量,以及getXxx()/setXxx(),还有eat()等都是相同的。
如果我们后来继续定义类,举例:工人类,军人类。他们是不是也具备这些内容。
那么,我们每一次定义这样的类的时候,都要把这些重复的内容都重新定义一遍。
麻烦不?麻烦。所以,我们要考虑改进?
如何改进呢?
我这想的:我能不能把这些相同的内容给定义到一个独立的类中。
然后,让这多个类和这个独立的类产生一个关系,有了这个关系后,
这多个类就可以具备这个独立的类的功能。
为了实现这个效果,java就提供了一个技术:继承。
 
父亲:
4个儿子
继承怎么表示呢?继承的格式是什么样子的呢?
class Fu {}
 
class Zi extends Fu {
 
}
 
我们就回头修改我们的代码:
class Person {
String name;
int age;
 
public Person(){}
 
//getXxx()/setXxx()
 
public void eat() {
System.out.println("吃饭");
}
}
 
class Student extends Person {
public Student(){}
}
 
class Teacher extends Person {
public Teacher(){}
}
===============================================================================================
1:方法重写和方法重载的区别?方法重载能改变返回值类型吗?
 
方法重写:
在子类中,出现和父类中一模一样的方法声明的现象。
 
方法重载:
同一个类中,出现的方法名相同,参数列表不同的现象。
 
 
方法重载能改变返回值类型,因为它和返回值类型无关。
 
 
Override:方法重写
Overload:方法重载
 
2:this关键字和super关键字分别代表什么?以及他们各自的使用场景和作用。
 
this:代表当前类的对象引用
super:代表父类存储空间的标识。(可以理解为父类的引用,通过这个东西可以访问父类的成员)
 
场景:
成员变量:
this.成员变量
super.成员变量
构造方法:
this(...)
super(...)
成员方法:
this.成员方法
super.成员方法
 
三.多态,抽象,接口
/*
final可以修饰类,方法,变量
 
特点:
final可以修饰类,该类不能被继承。
final可以修饰方法,该方法不能被重写。(覆盖,复写)
final可以修饰变量,该变量不能被重新赋值。因为这个变量其实常量。
 
常量:
A:字面值常量
"hello",10,true
B:自定义常量
final int x = 10;
*/
 
//final class Fu //无法从最终Fu进行继承
 
class Fu {
public int num = 10;
public final int num2 = 20;
 
/*
public final void show() {
 
}
*/
}
 
class Zi extends Fu {
// Zi中的show()无法覆盖Fu中的show()
public void show() {
num = 100;
System.out.println(num);
 
//无法为最终变量num2分配值
//num2 = 200;
System.out.println(num2);
}
}
 
class FinalDemo {
public static void main(String[] args) {
Zi z = new Zi();
z.show();
}
}
===============================================================
/*
面试题:final修饰局部变量的问题
基本类型:基本类型的值不能发生改变。
引用类型:引用类型的地址值不能发生改变,但是,该对象的堆内存的值是可以改变的。
*/
class Student {
int age = 10;
}
 
class FinalTest {
public static void main(String[] args) {
//局部变量是基本数据类型
int x = 10;
x = 100;
System.out.println(x);
int y = 10;
//无法为最终变量y分配值
//y = 100;
System.out.println(y);
System.out.println("--------------");
 
//局部变量是引用数据类型
Student s = new Student();
System.out.println(s.age);
s.age = 100;
System.out.println(s.age);
System.out.println("--------------");
 
final Student ss = new Student();
System.out.println(ss.age);
ss.age = 100;
System.out.println(ss.age);
 
//重新分配内存空间
//无法为最终变量ss分配值
//ss = new Student();
 
//100
100
=================
10
100
10
100
}
}
========================================================================================
/*
final修饰变量的初始化时机
A:被final修饰的变量只能赋值一次。
B:在构造方法完毕前。(非静态的常量)
*/
class Demo {
//int num = 10;
//final int num2 = 20;
 
int num;
final int num2;
 
{
//num2 = 10;
}
 
public Demo() {
num = 100;
//无法为最终变量num2分配值
num2 = 200;
}
}
 
class FinalTest2 {
public static void main(String[] args) {
Demo d = new Demo();
System.out.println(d.num);
System.out.println(d.num2);
}
}
==============================================
/*
继承的代码体现
 
由于继承中方法有一个现象:方法重写。
所以,父类的功能,就会被子类给覆盖调。
有些时候,我们不想让子类去覆盖掉父类的功能,只能让他使用。
这个时候,针对这种情况,Java就提供了一个关键字:final
 
final:最终的意思。常见的是它可以修饰类,方法,变量。
*/
class Fu {
public final void show() {
System.out.println("这里是绝密资源,任何人都不能修改");
}
}
 
class Zi extends Fu {
// Zi中的show()无法覆盖Fu中的show()
public void show() {
System.out.println("这是一堆垃圾");
}
}
 
class ZiDemo {
public static void main(String[] args) {
Zi z = new Zi();
z.show();
}
}
======================================================
/*
多态:同一个对象(事物),在不同时刻体现出来的不同状态。
举例:
猫是猫,猫是动物。
水(液体,固体,气态)。
 
多态的前提:
A:要有继承关 系。
B:要有方法重写。
其实没有也是可以的,但是如果没有这个就没有意义。
动物 d = new 猫();
d.show();
动物 d = new 狗();
d.show();
C:要有父类引用指向子类对象。
父 f = new 子();
 
用代码体现一下多态。
 
多态中的成员访问特点:
A:成员变量
编译看左边,运行看左边。
B:构造方法
创建子类对象的时候,访问父类的构造方法,对父类的数据进行初始化。
C:成员方法
编译看左边,运行看右边。
D:静态方法
编译看左边,运行看左边。
(静态和类相关,算不上重写,所以,访问还是左边的)
 
由于成员方法存在方法重写,所以它运行看右边。
*/
class Fu {
public int num = 100;
 
public void show() {
System.out.println("show Fu");
}
 
public static void function() {
System.out.println("function Fu");
}
}
 
class Zi extends Fu {
public int num = 1000;
public int num2 = 200;
 
public void show() {
System.out.println("show Zi");
}
 
public void method() {
System.out.println("method zi");
}
 
public static void function() {
System.out.println("function Zi");
}
}
 
class DuoTaiDemo {
public static void main(String[] args) {
//要有父类引用指向子类对象。
//父 f = new 子();
Fu f = new Zi();
System.out.println(f.num);//100
//找不到符号
//System.out.println(f.num2);
 
f.show();//show zi
//找不到符号
//f.method();
f.function();//function fu
 
}
}
==========================================================
/*
多态的好处:
A:提高了代码的维护性(继承保证)
B:提高了代码的扩展性(由多态保证)
 
猫狗案例代码
*/
class Animal {
public void eat(){
System.out.println("eat");
}
 
public void sleep(){
System.out.println("sleep");
}
}
 
class Dog extends Animal {
public void eat(){
System.out.println("狗吃肉");
}
 
public void sleep(){
System.out.println("狗站着睡觉");
}
}
 
class Cat extends Animal {
public void eat() {
System.out.println("猫吃鱼");
}
 
public void sleep() {
System.out.println("猫趴着睡觉");
}
}
 
class Pig extends Animal {
public void eat() {
System.out.println("猪吃白菜");
}
 
public void sleep() {
System.out.println("猪侧着睡");
}
}
 
//针对动物操作的工具类
class AnimalTool {
private AnimalTool(){}
 
/*
//调用猫的功能
public static void useCat(Cat c) {
c.eat();
c.sleep();
}
 
//调用狗的功能
public static void useDog(Dog d) {
d.eat();
d.sleep();
}
 
//调用猪的功能
public static void usePig(Pig p) {
p.eat();
p.sleep();
}
*/
public static void useAnimal(Animal a) {
a.eat();
a.sleep();
}
 
}
 
class DuoTaiDemo2 {
public static void main(String[] args) {
//我喜欢猫,就养了一只
Cat c = new Cat();
c.eat();
c.sleep();
 
//我很喜欢猫,所以,又养了一只
Cat c2 = new Cat();
c2.eat();
c2.sleep();
 
//我特别喜欢猫,又养了一只
Cat c3 = new Cat();
c3.eat();
c3.sleep();
//...
System.out.println("--------------");
//问题来了,我养了很多只猫,每次创建对象是可以接受的
//但是呢?调用方法,你不觉得很相似吗?仅仅是对象名不一样。
//我们准备用方法改进
//调用方式改进版本
//useCat(c);
//useCat(c2);
//useCat(c3);
 
//AnimalTool.useCat(c);
//AnimalTool.useCat(c2);
//AnimalTool.useCat(c3);
 
AnimalTool.useAnimal(c);
AnimalTool.useAnimal(c2);
AnimalTool.useAnimal(c3);
System.out.println("--------------");
 
//我喜欢狗
Dog d = new Dog();
Dog d2 = new Dog();
Dog d3 = new Dog();
//AnimalTool.useDog(d);
//AnimalTool.useDog(d2);
//AnimalTool.useDog(d3);
AnimalTool.useAnimal(d);
AnimalTool.useAnimal(d2);
AnimalTool.useAnimal(d3);
System.out.println("--------------");
 
//我喜欢宠物猪
//定义一个猪类,它要继承自动物,提供两个方法,并且还得在工具类中添加该类方法调用
Pig p = new Pig();
Pig p2 = new Pig();
Pig p3 = new Pig();
//AnimalTool.usePig(p);
//AnimalTool.usePig(p2);
//AnimalTool.usePig(p3);
AnimalTool.useAnimal(p);
AnimalTool.useAnimal(p2);
AnimalTool.useAnimal(p3);
System.out.println("--------------");
 
//我喜欢宠物狼,老虎,豹子...
//定义对应的类,继承自动物,提供对应的方法重写,并在工具类添加方法调用
//前面几个必须写,我是没有意见的
//但是,工具类每次都改,麻烦不
//我就想,你能不能不改了
//太简单:把所有的动物都写上。问题是名字是什么呢?到底哪些需要被加入呢?
//改用另一种解决方案。
 
}
 
/*
//调用猫的功能
public static void useCat(Cat c) {
c.eat();
c.sleep();
}
 
//调用狗的功能
public static void useDog(Dog d) {
d.eat();
d.sleep();
}
*/
}
====================================================================/*
多态的弊端:
不能使用子类的特有功能。
*/
class Fu {
public void show() {
System.out.println("show fu");
}
}
 
class Zi extends Fu {
public void show() {
System.out.println("show zi");
}
 
public void method() {
System.out.println("method zi");
}
 
}
 
class DuoTaiDemo3 {
public static void main(String[] args) {
//测试
Fu f = new Zi();
f.show();
//f.method();//不能访问
}
}
=========================================================
/*
多态的弊端:
不能使用子类的特有功能。
 
我就想使用子类的特有功能?行不行?
行。
 
怎么用呢?
A:创建子类对象调用方法即可。(可以,但是很多时候不合理。而且,太占内存了)
B:把父类的引用强制转换为子类的引用。(向下转型)
 
对象间的转型问题:
向上转型:
Fu f = new Zi();
向下转型:
Zi z = (Zi)f; //要求该f必须是能够转换为Zi的。
*/
class Fu {
public void show() {
System.out.println("show fu");
}
}
 
class Zi extends Fu {
public void show() {
System.out.println("show zi");
}
 
public void method() {
System.out.println("method zi");
}
 
}
 
class DuoTaiDemo4 {
public static void main(String[] args) {
//测试
Fu f = new Zi();
f.show();
//f.method();
 
//创建子类对象
//Zi z = new Zi();
//z.show();
//z.method();
 
//你能够把子的对象赋值给父亲,那么我能不能把父的引用赋值给子的引用呢?
//如果可以,但是如下
Zi z = (Zi)f;
z.show();
z.method();
}
}
===========================================================
多态的问题理解:
class 孔子爹 {
public int age = 40;
 
public void teach() {
System.out.println("讲解JavaSE");
}
}
 
class 孔子 extends 孔子爹 {
public int age = 20;
 
public void teach() {
System.out.println("讲解论语");
}
 
public void playGame() {
System.out.println("英雄联盟");
}
}
 
//Java培训特别火,很多人来请孔子爹去讲课,这一天孔子爹被请走了
//但是还有人来请,就剩孔子在家,价格还挺高。孔子一想,我是不是可以考虑去呢?
//然后就穿上爹的衣服,带上爹的眼睛,粘上爹的胡子。就开始装爹
//向上转型
孔子爹 k爹 = new 孔子();
//到人家那里去了
System.out.println(k爹.age); //40
k爹.teach(); //讲解论语
//k爹.playGame(); //这是儿子才能做的
 
 
//讲完了,下班回家了
//脱下爹的装备,换上自己的装备
//向下转型
孔子 k = (孔子) k爹;
System.out.println(k.age); //20
k.teach(); //讲解论语
k.playGame(); //英雄联盟
 
====================================================================/*
ClassCastException:类型转换异常
一般在多态的向下转型中容易出现
*/
class Animal {
public void eat(){}
}
 
class Dog extends Animal {
public void eat() {}
 
public void lookDoor() {
 
}
}
 
class Cat extends Animal {
public void eat() {
 
}
 
public void playGame() {
 
}
}
 
class DuoTaiDemo5 {
public static void main(String[] args) {
//内存中的是狗
Animal a = new Dog();
Dog d = (Dog)a;
 
//内存中是猫
a = new Cat();
Cat c = (Cat)a;
 
//内存中是猫
Dog dd = (Dog)a; //ClassCastException
}
}
=================================================
/*
多态练习:猫狗案例
*/
class Animal {
public void eat(){
System.out.println("吃饭");
}
}
 
class Dog extends Animal {
public void eat() {
System.out.println("狗吃肉");
}
 
public void lookDoor() {
System.out.println("狗看门");
}
}
 
class Cat extends Animal {
public void eat() {
System.out.println("猫吃鱼");
}
 
public void playGame() {
System.out.println("猫捉迷藏");
}
}
 
class DuoTaiTest {
public static void main(String[] args) {
//定义为狗
Animal a = new Dog();
a.eat();
System.out.println("--------------");
//还原成狗
Dog d = (Dog)a;
d.eat();
d.lookDoor();
System.out.println("--------------");
//变成猫
a = new Cat();
a.eat();
System.out.println("--------------");
//还原成猫
Cat c = (Cat)a;
c.eat();
c.playGame();
System.out.println("--------------");
 
//演示错误的内容
//Dog dd = new Animal();
//Dog ddd = new Cat();
//ClassCastException
//Dog dd = (Dog)a;
}
}
 
===============================================
/*
不同地方饮食文化不同的案例
*/
class Person {
public void eat() {
System.out.println("吃饭");
}
}
 
class SouthPerson extends Person {
public void eat() {
System.out.println("炒菜,吃米饭");
}
 
public void jingShang() {
System.out.println("经商");
}
}
 
class NorthPerson extends Person {
public void eat() {
System.out.println("炖菜,吃馒头");
}
 
public void yanJiu() {
System.out.println("研究");
}
}
 
class DuoTaiTest2 {
public static void main(String[] args) {
//测试
//南方人
Person p = new SouthPerson();
p.eat();
System.out.println("-------------");
SouthPerson sp = (SouthPerson)p;
sp.eat();
sp.jingShang();
System.out.println("-------------");
 
//北方人
p = new NorthPerson();
p.eat();
System.out.println("-------------");
NorthPerson np = (NorthPerson)p;
np.eat();
np.yanJiu();
}
}
===================================================
/*
看程序写结果:先判断有没有问题,如果没有,写出结果
*/
class Fu {
public void show() {
System.out.println("fu show");
}
}
 
class Zi extends Fu {
public void show() {
System.out.println("zi show");
}
 
public void method() {
System.out.println("zi method");
}
}
 
class DuoTaiTest3 {
public static void main(String[] args) {
Fu f = new Zi();
//找不到符号
//f.method();
f.show(); //zi show
}
}
==========================================================
/*
看程序写结果:先判断有没有问题,如果没有,写出结果
 
多态的成员访问特点:
方法:编译看左边,运行看右边。
 
继承的时候:
子类中有和父类中一样的方法,叫重写。
子类中没有父亲中出现过的方法,方法就被继承过来了。
*/
class A {
public void show() {
show2();
}
public void show2() {
System.out.println("我");
}
}
class B extends A {
/*
public void show() {
show2();
}
*/
 
public void show2() {
System.out.println("爱");
}
}
class C extends B {
public void show() {
super.show();
}
public void show2() {
System.out.println("你");
}
}
public class DuoTaiTest4 {
public static void main(String[] args) {
A a = new B();
a.show();
 
B b = new C();
b.show();
}
}
====================================================================
/*
抽象类的概述:
动物不应该定义为具体的东西,而且动物中的吃,睡等也不应该是具体的。
我们把一个不是具体的功能称为抽象的功能,而一个类中如果有抽象的功能,该类必须是抽象类。
 
抽象类的特点:
A:抽象类和抽象方法必须用abstract关键字修饰
B:抽象类中不一定有抽象方法,但是有抽象方法的类必须定义为抽象类
C:抽象类不能实例化 不能创建对象
因为它不是具体的。
抽象类有构造方法,但是不能实例化?构造方法的作用是什么呢?
用于子类访问父类数据的初始化
D:抽象的子类
a:如果不想重写抽象方法,该子类是一个抽象类。
b:重写所有的抽象方法,这个时候子类是一个具体的类。
 
抽象类的实例化其实是靠具体的子类实现的。是多态的方式。
Animal a = new Cat();
*/
 
//abstract class Animal //抽象类的声明格式
abstract class Animal {
//抽象方法
//public abstract void eat(){} //空方法体,这个会报错。抽象方法不能有主体
public abstract void eat();
 
public Animal(){}
}
 
//子类是抽象类
abstract class Dog extends Animal {}
 
//子类是具体类,重写抽象方法
class Cat extends Animal {
public void eat() {
System.out.println("猫吃鱼");
}
}
 
class AbstractDemo {
public static void main(String[] args) {
//创建对象
//Animal是抽象的; 无法实例化
//Animal a = new Animal();
//通过多态的方式
Animal a = new Cat();
a.eat();
}
}
====================================================================
/*
抽象类的成员特点:
成员变量:既可以是变量,也可以是常量。
构造方法:有。
用于子类访问父类数据的初始化。
成员方法:既可以是抽象的,也可以是非抽象的。
 
抽象类的成员方法特性:
A:抽象方法 强制要求子类做的事情。
B:非抽象方法 子类继承的事情,提高代码复用性。
*/
abstract class Animal {
public int num = 10;
public final int num2 = 20;
 
public Animal() {}
 
public Animal(String name,int age){}
 
public abstract void show();
 
public void method() {
System.out.println("method");
}
}
 
class Dog extends Animal {
public void show() {
System.out.println("show Dog");
}
}
 
class AbstractDemo2 {
public static void main(String[] args) {
//创建对象
Animal a = new Dog();
a.num = 100;
System.out.println(a.num);
//a.num2 = 200;
System.out.println(a.num2);
System.out.println("--------------");
a.show();
a.method();
}
}
==============================================
/*
一个类如果没有抽象方法,可不可以定义为抽象类?如果可以,有什么意义?
A:可以。
B:不让创建对象。
 
abstract不能和哪些关键字共存?
private 冲突
final 冲突
static 无意义
*/
abstract class Fu {
//public abstract void show();
//非法的修饰符组合: abstract和private
//private abstract void show();
 
//非法的修饰符组合
//final abstract void show();
 
//非法的修饰符组合
static abstract void show();
 
public static void method() {
System.out.println("method");
}
}
 
class Zi extends Fu {
public void show() {}
}
 
class AbstractDemo3 {
public static void main(String[] args) {
Fu.method();
}
}
==================================
/*
猫狗案例
具体事物:猫,狗
共性:姓名,年龄,吃饭
 
分析:从具体到抽象
猫:
成员变量:姓名,年龄
构造方法:无参,带参
成员方法:吃饭(猫吃鱼)
 
狗:
成员变量:姓名,年龄
构造方法:无参,带参
成员方法:吃饭(狗吃肉)
 
因为有共性的内容,所以就提取了一个父类。动物。
但是又由于吃饭的内容不一样,所以吃饭的方法是抽象的,
而方法是抽象的类,类就必须定义为抽象类。
 
抽象动物类:
成员变量:姓名,年龄
构造方法:无参,带参
成员方法:吃饭();
 
实现:从抽象到具体
动物类:
成员变量:姓名,年龄
构造方法:无参,带参
成员方法:吃饭();
 
狗类:
继承自动物类
重写吃饭();
 
猫类:
继承自动物类
重写吃饭();
*/
//定义抽象的动物类
abstract class Animal {
//姓名
private String name;
//年龄
private int age;
 
public Animal() {}
 
public Animal(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();
}
 
//定义具体的狗类
class Dog extends Animal {
public Dog() {}
 
public Dog(String name,int age) {
super(name,age);
}
 
public void eat() {
System.out.println("狗吃肉");
}
}
 
//定义具体的猫类
class Cat extends Animal {
public Cat() {}
 
public Cat(String name,int age) {
super(name,age);
}
 
public void eat() {
System.out.println("猫吃鱼");
}
}
 
//测试类
class AbstractTest {
public static void main(String[] args) {
//测试狗类
//具体类用法
//方式1:
Dog d = new Dog();
d.setName("旺财");
d.setAge(3);
System.out.println(d.getName()+"---"+d.getAge());
d.eat();
//方式2:
Dog d2 = new Dog("旺财",3);
System.out.println(d2.getName()+"---"+d2.getAge());
d2.eat();
System.out.println("---------------------------");
 
Animal a = new Dog();
a.setName("旺财");
a.setAge(3);
System.out.println(a.getName()+"---"+a.getAge());
a.eat();
 
Animal a2 = new Dog("旺财",3);
System.out.println(a2.getName()+"---"+a2.getAge());
a2.eat();
 
//练习:测试猫类
}
}
 
====================================================================
/*
老师案例
具体事物:基础班老师,就业班老师
共性:姓名,年龄,讲课。
 
分析:
基础班老师
姓名,年龄
讲课。
就业班老师
姓名,年龄
讲课。
实现:
老师类
基础班老师
就业班老师
*/
//定义抽象的老师类
abstract class Teacher {
//姓名
private String name;
//年龄
private int age;
 
public Teacher() {}
 
public Teacher(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 teach();
}
 
//基础班老师类
class BasicTeacher extends Teacher {
public BasicTeacher(){}
 
public BasicTeacher(String name,int age) {
super(name,age);
}
 
public void teach() {
System.out.println("基础班老师讲解JavaSE");
}
}
 
//就业班老师类
class WorkTeacher extends Teacher {
public WorkTeacher(){}
 
public WorkTeacher(String name,int age) {
super(name,age);
}
 
public void teach() {
System.out.println("就业班老师讲解JavaEE");
}
}
 
class AbstractTest2 {
public static void main(String[] args) {
//具体的类测试,自己玩
 
//测试(多态)
//基础班老师
Teacher t = new BasicTeacher();
t.setName("刘意");
t.setAge(30);
System.out.println(t.getName()+"---"+t.getAge());
t.teach();
System.out.println("--------------");
 
t = new BasicTeacher("刘意",30);
System.out.println(t.getName()+"---"+t.getAge());
t.teach();
System.out.println("--------------");
 
//就业班老师
t = new WorkTeacher();
t.setName("林青霞");
t.setAge(27);
System.out.println(t.getName()+"---"+t.getAge());
t.teach();
System.out.println("--------------");
 
t = new WorkTeacher("林青霞",27);
System.out.println(t.getName()+"---"+t.getAge());
t.teach();
}
}
==========================================================
/*
学生案例
具体事务:基础班学员,就业班学员
共性:姓名,年龄,班级,学习,吃饭
 
分析:
基础班学员
成员变量:姓名,年龄,班级
成员方法:学习,吃饭
就业班学员
成员变量:姓名,年龄,班级
成员方法:学习,吃饭
 
得到一个学员类。
成员变量:姓名,年龄,班级
成员方法:学习,吃饭
 
实现:
学员类
基础班学员
就业班学员
*/
//定义抽象学员类
abstract class Student {
//姓名
private String name;
//年龄
private int age;
//班级
private String grand;
 
public Student() {}
 
public Student(String name,int age,String grand) {
this.name = name;
this.age = age;
this.grand = grand;
}
 
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 String getGrand() {
return grand;
}
 
public void setGrand(String grand) {
this.grand = grand;
}
 
//学习
public abstract void study();
 
//吃饭
public void eat() {
System.out.println("学习累了,就该吃饭");
}
}
 
//具体基础班学员类
class BasicStudent extends Student {
public BasicStudent() {}
 
public BasicStudent(String name,int age,String grand) {
super(name,age,grand);
}
 
public void study() {
System.out.println("基础班学员学习的是JavaSE");
}
}
 
//具体就业班学员类
class WorkStudent extends Student {
public WorkStudent() {}
 
public WorkStudent(String name,int age,String grand) {
super(name,age,grand);
}
 
public void study() {
System.out.println("就业班学员学习的是JavaEE");
}
}
 
class AbstractTest3 {
public static void main(String[] args) {
//我仅仅测试基础班学员
//按照多态的方式测试
Student s = new BasicStudent();
s.setName("林青霞");
s.setAge(27);
s.setGrand("1111");
System.out.println(s.getName()+"---"+s.getAge()+"---"+s.getGrand());
s.study();
s.eat();
System.out.println("--------------");
 
s = new BasicStudent("武鑫",48,"1111");
System.out.println(s.getName()+"---"+s.getAge()+"---"+s.getGrand());
s.study();
s.eat();
 
//就业班测试留给自己玩
}
}
====================================================================/*
假如我们在开发一个系统时需要对员工类进行设计,员工包含3个属性:姓名、工号以及工资。
经理也是员工,除了含有员工的属性外,另为还有一个奖金属性。
请使用继承的思想设计出员工类和经理类。要求类中提供必要的方法进行属性访问。
 
分析:
普通员工类
成员变量:姓名、工号以及工资。
成员方法:工作
经理类:
成员变量:姓名、工号以及工资,奖金属性
成员方法:工作
 
实现:
员工类:
普通员工类:
经理类:
*/
//定义员工类
abstract class Employee {
//姓名、工号以及工资
private String name;
private String id;
private int salary;
 
public Employee() {}
 
public Employee(String name,String id,int salary) {
this.name = name;
this.id = id;
this.salary = salary;
}
 
public String getName() {
return name;
}
 
public void setName(String name) {
this.name = name;
}
 
public String getId() {
return id;
}
 
public void setId(String id) {
this.id = id;
}
 
public int getSalary() {
return salary;
}
 
public void setSalary(int salary) {
this.salary = salary;
}
 
//工作
public abstract void work();
}
 
//普通员工类
class Programmer extends Employee {
public Programmer(){}
 
public Programmer(String name,String id,int salary) {
super(name,id,salary);
}
 
public void work() {
System.out.println("按照需求写代码");
}
}
 
//经理类
class Manager extends Employee {
//奖金
private int money; //bonus 奖金
 
public Manager(){}
 
public Manager(String name,String id,int salary,int money) {
super(name,id,salary);
this.money = money;
}
 
public void work() {
System.out.println("跟客户谈需求");
}
 
public int getMoney() {
return money;
}
 
public void setMoney(int money) {
this.money = money;
}
}
 
class AbstractTest4 {
public static void main(String[] args) {
//测试普通员工
Employee emp = new Programmer();
emp.setName("林青霞");
emp.setId("czbk001");
emp.setSalary(18000);
System.out.println(emp.getName()+"---"+emp.getId()+"---"+emp.getSalary());
emp.work();
System.out.println("-------------");
emp = new Programmer("林青霞","czbk001",18000);
System.out.println(emp.getName()+"---"+emp.getId()+"---"+emp.getSalary());
emp.work();
System.out.println("-------------");
 
/*
emp = new Manager();
emp.setName("刘意");
emp.setId("czbk002");
emp.setSalary(8000);
emp.setMoney(2000);
*/
//由于子类有特有的内容,所以我们用子类来测试
Manager m = new Manager();
m.setName("刘意");
m.setId("czbk002");
m.setSalary(8000);
m.setMoney(2000);
System.out.println(m.getName()+"---"+m.getId()+"---"+m.getSalary()+"---"+m.getMoney());
m.work();
System.out.println("-------------");
 
//通过构造方法赋值
m = new Manager("刘意","czbk002",8000,2000);
System.out.println(m.getName()+"---"+m.getId()+"---"+m.getSalary()+"---"+m.getMoney());
m.work();
}
}
====================================================================
/*
接口的特点:
A:接口用关键字interface表示
interface 接口名 {}
B:类实现接口用implements表示
class 类名 implements 接口名 {}
C:接口不能实例化
那么,接口如何实例化呢?
按照多态的方式来实例化。
D:接口的子类
a:可以是抽象类。但是意义不大。
b:可以是具体类。要重写接口中的所有抽象方法。(推荐方案)
 
由此可见:
A:具体类多态(几乎没有)
B:抽象类多态(常用)
C:接口多态(最常用)
*/
//定义动物培训接口
interface AnimalTrain {
public abstract void jump();
}
 
//抽象类实现接口
abstract class Dog implements AnimalTrain {
}
 
//具体类实现接口
class Cat implements AnimalTrain {
public void jump() {
System.out.println("猫可以跳高了");
}
}
 
class InterfaceDemo {
public static void main(String[] args) {
//AnimalTrain是抽象的; 无法实例化
//AnimalTrain at = new AnimalTrain();
//at.jump();
 
AnimalTrain at = new Cat();
at.jump();
}
}
==========================================
/*
接口成员特点
成员变量;只能是常量,并且是静态的。
默认修饰符:public static final
建议:自己手动给出。
构造方法:接口没有构造方法。
成员方法:只能是抽象方法。
默认修饰符:public abstract
建议:自己手动给出。
 
所有的类都默认继承自一个类:Object。
类 Object 是类层次结构的根类。每个类都使用 Object 作为超类。
*/
interface Inter {
public int num = 10;
public final int num2 = 20;
public static final int num3 = 30;
 
//错误: 需要<标识符>
//public Inter() {}
 
//接口方法不能带有主体
//public void show() {}
 
//abstract void show(); //默认public
public void show(); //默认abstract
}
 
//接口名+Impl这种格式是接口的实现类格式
/*
class InterImpl implements Inter {
public InterImpl() {
super();
}
}
*/
 
class InterImpl extends Object implements Inter {
public InterImpl() {
super();
}
 
public void show() {}
}
 
//测试类
class InterfaceDemo2 {
public static void main(String[] args) {
//创建对象
Inter i = new InterImpl();
System.out.println(i.num);
System.out.println(i.num2);
//i.num = 100;
//i.num2 = 200;
//System.out.println(i.num); //无法为最终变量num分配值
//System.out.println(i.num2);//无法为最终变量num2分配值
System.out.println(Inter.num);
System.out.println(Inter.num2);
System.out.println("--------------");
}
}
==========================================================
/*
类与类:
继承关系,只能单继承,可以多层继承。
类与接口:
实现关系,可以单实现,也可以多实现。
并且还可以在继承一个类的同时实现多个接口。
接口与接口:
继承关系,可以单继承,也可以多继承。
*/
interface Father {
public abstract void show();
}
 
interface Mother {
public abstract void show2();
}
 
interface Sister extends Father,Mother {
 
}
 
//class Son implements Father,Mother //多实现
class Son extends Object implements Father,Mother {
public void show() {
System.out.println("show son");
}
 
public void show2() {
System.out.println("show2 son");
}
}
 
class InterfaceDemo3 {
public static void main(String[] args) {
//创建对象
Father f = new Son();
f.show();
//f.show2(); //报错
 
Mother m = new Son();
//m.show(); //报错
m.show2();
}
}
====================================================================/*
猫狗案例,加入跳高的额外功能
 
分析:从具体到抽象
猫:
姓名,年龄
吃饭,睡觉
狗:
姓名,年龄
吃饭,睡觉
 
由于有共性功能,所以,我们抽取出一个父类:
动物:
姓名,年龄
吃饭();
睡觉(){}
 
猫:继承自动物
狗:继承自动物
 
跳高的额外功能是一个新的扩展功能,所以我们要定义一个接口
接口:
跳高
 
部分猫:实现跳高
部分狗:实现跳高
实现;
从抽象到具体
 
使用:
使用具体类
*/
//定义跳高接口
interface Jumpping {
//跳高功能
public abstract void jump();
}
 
//定义抽象类
abstract class Animal {
//姓名
private String name;
//年龄
private int age;
 
public Animal() {}
 
public Animal(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();
 
//睡觉(){}
public void sleep() {
System.out.println("睡觉觉了");
}
}
 
//具体猫类
class Cat extends Animal {
public Cat(){}
 
public Cat(String name,int age) {
super(name,age);
}
 
public void eat() {
System.out.println("猫吃鱼");
}
}
 
//具体狗类
class Dog extends Animal {
public Dog(){}
 
public Dog(String name,int age) {
super(name,age);
}
 
public void eat() {
System.out.println("狗吃肉");
}
}
 
//有跳高功能的猫
class JumpCat extends Cat implements Jumpping {
public JumpCat() {}
 
public JumpCat(String name,int age) {
super(name,age);
}
 
public void jump() {
System.out.println("跳高猫");
}
}
 
//有跳高功能的狗
class JumpDog extends Dog implements Jumpping {
public JumpDog() {}
 
public JumpDog(String name,int age) {
super(name,age);
}
 
public void jump() {
System.out.println("跳高狗");
}
}
 
class InterfaceTest {
public static void main(String[] args) {
//定义跳高猫并测试
JumpCat jc = new JumpCat();
jc.setName("哆啦A梦");
jc.setAge(3);
System.out.println(jc.getName()+"---"+jc.getAge());
jc.eat();
jc.sleep();
jc.jump();
System.out.println("-----------------");
 
JumpCat jc2 = new JumpCat("加菲猫",2);
System.out.println(jc2.getName()+"---"+jc2.getAge());
jc2.eat();
jc2.sleep();
jc2.jump();
 
//定义跳高狗并进行测试的事情自己完成。
}
}
===================================================================
/*
老师和学生案例,加入抽烟的额外功能
 
分析:从具体到抽象
老师:姓名,年龄,吃饭,睡觉
学生:姓名,年龄,吃饭,睡觉
 
由于有共性功能,我们提取出一个父类,人类。
 
人类:
姓名,年龄
吃饭();
睡觉(){}
 
抽烟的额外功能不是人或者老师,或者学生一开始就应该具备的,所以,我们把它定义为接口
 
抽烟接口。
 
部分老师抽烟:实现抽烟接口
部分学生抽烟:实现抽烟接口
 
实现:从抽象到具体
 
使用:具体
*/
//定义抽烟接口
interface Smoking {
//抽烟的抽象方法
public abstract void smoke();
}
 
//定义抽象人类
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();
 
//睡觉(){}
public void sleep() {
System.out.println("睡觉觉了");
}
}
 
//具体老师类
class Teacher extends Person {
public Teacher() {}
 
public Teacher(String name,int age) {
super(name,age);
}
 
public void eat() {
System.out.println("吃大白菜");
}
}
 
//具体学生类
class Student extends Person {
public Student() {}
 
public Student(String name,int age) {
super(name,age);
}
 
public void eat() {
System.out.println("吃红烧肉");
}
}
 
//抽烟的老师
class SmokingTeacher extends Teacher implements Smoking {
public SmokingTeacher() {}
 
public SmokingTeacher(String name,int age) {
super(name,age);
}
 
public void smoke() {
System.out.println("抽烟的老师");
}
}
 
//抽烟的学生
class SmokingStudent extends Student implements Smoking {
public SmokingStudent() {}
 
public SmokingStudent(String name,int age) {
super(name,age);
}
 
public void smoke() {
System.out.println("抽烟的学生");
}
}
 
class InterfaceTest2 {
public static void main(String[] args) {
//测试学生
SmokingStudent ss = new SmokingStudent();
ss.setName("林青霞");
ss.setAge(27);
System.out.println(ss.getName()+"---"+ss.getAge());
ss.eat();
ss.sleep();
ss.smoke();
System.out.println("-------------------");
 
SmokingStudent ss2 = new SmokingStudent("刘意",30);
System.out.println(ss2.getName()+"---"+ss2.getAge());
ss2.eat();
ss2.sleep();
ss2.smoke();
 
//测试老师留给自己练习
}
}
====================================================================抽象类和接口的区别:
A:成员区别
抽象类:
成员变量:可以变量,也可以常量
构造方法:有
成员方法:可以抽象,也可以非抽象
接口:
成员变量:只可以常量
成员方法:只可以抽象
 
B:关系区别
类与类
继承,单继承
类与接口
实现,单实现,多实现
接口与接口
继承,单继承,多继承
 
C:设计理念区别
抽象类 被继承体现的是:”is a”的关系。抽象类中定义的是该继承体系的共性功能。
接口 被实现体现的是:”like a”的关系。接口中定义的是该继承体系的扩展功能。
 
四.匿名内部类
package cn.itcast_03;
 
import java.util.ArrayList;
import java.util.Date;
import java.util.Scanner;
 
/*
* 常用快捷键
* 1:格式化 ctrl+shift+f
* 2:导入包 ctrl+shift+o
* 如果该类仅仅在一个包中有,就自己显示了
* 如果该类在多个包中有,会弹出一个框框供你选择
* 3:注释
* 单行:注释 ctrl+/,取消注释再来一次。
* 多行:ctrl+shift+/,ctrl+shift+
* 4:代码上下移动
* 选中代码alt+上/下箭头
* 5:查看源码
* 选中类名(F3或者Ctrl+鼠标点击)
*/
public class HelloWorld {
public static void main(String[] args) {
int a = 10;
System.out.println(a);
 
Scanner sc = new Scanner(System.in);
Date d = new Date();
 
// StringBuffer
// ArrayList<E>
 
Math.random();
}
}
============================================================
package cn.itcast_03;
 
import cn.itcast_01.HelloWorld;
 
/*
* alt+/ 内容辅助键
*
* A:main方法
* main+alt+/ 回车即可
* B:输出语句
* syso+alt+/
* C:提示作用
* 帮助你补齐一些你你不住的东西,还可以帮你起名字等。
*/
public class Demo {
// public static void main(String[] args) {
// System.out.println("HelloWorld");
// }
 
public static void main(String[] args) {
System.out.println();
 
String string = new String();
 
HelloWorld helloWorld = new HelloWorld();
 
 
}
}
 
=============================================================
package cn.itcast_04;
 
/*
* 提高开发效率:
* A:帮助我们自动提供构造方法
a:无参构造方法
在代码区域右键--source--Generate Constructors from Superclass
b:带参构造方法
在代码区域右键--source--Generate Constructors using fields.. -- finish
 
B:成对的getXxx()和setXxx()
在代码区域右键--source--Generate Getters and Setters...
*/
public class Student {
// 成员变量
private String name;
private int age;
 
//构造方法
public Student() {
super();
}
 
public Student(String name, int age) {
super();
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;
}
 
 
 
}
 
==========================================
package cn.itcast_04;
 
public class Teacher {
// 成员变量
private String name;
private int age;
 
public Teacher(String name, int age) {
super();
this.name = name;
this.age = age;
}
 
public Teacher() {
super();
// TODO Auto-generated constructor stub
}
 
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;
}
 
}
=====================================
package cn.itcast_01;
 
public class Student {
// 姓名
private String name;
// 年龄
private int age;
 
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
 
public Student() {
super();
}
 
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 show() {
System.out.println("姓名:" + name + ",年龄:" + age);
}
}
 
package cn.itcast_01;
 
/*
* 测试类
*/
public class StudentDemo {
public static void main(String[] args) {
// 创建对象
Student s1 = new Student();
s1.setName("风清扬");
s1.setAge(30);
System.out.println(s1.getName() + "---" + s1.getAge());
s1.show();
 
// 创建对象
Student s2 = new Student("林青霞", 27);
System.out.println(s2.getName() + "---" + s2.getAge());
s2.show();
}
}
 
========================================================
package cn.itcast_03;
 
/*
* 通过debug查看程序执行流程
* 请大家也做一遍。 F6执行下一步
*/
public class ArgsDemo {
public static void main(String[] args) {
int a = 10;
int b = 20;
System.out.println("a:" + a + ",b:" + b);
change(a, b);
System.out.println("a:" + a + ",b:" + b);
 
int[] arr = { 1, 2, 3, 4, 5 };
change(arr);
System.out.println(arr[1]);
}
 
public static void change(int a, int b) {
System.out.println("a:" + a + ",b:" + b);
a = b;
b = a + b;
System.out.println("a:" + a + ",b:" + b);
}
 
public static void change(int[] arr) {
for (int x = 0; x < arr.length; x++) {
if (arr[x] % 2 == 0) {
arr[x] *= 2;
}
}
}
}
 
======================================
package cn.itcast_01;
 
/*
* Object:类 Object 是类层次结构的根类。每个类都使用 Object 作为超类。
* 每个类都直接或者间接的继承自Object类。
*
* Object类的方法:
* public int hashCode():返回该对象的哈希码值。
* 注意:哈希值是根据哈希算法计算出来的一个值,这个值和地址值有关,但是不是实际地址值。
* 你可以理解为地址值。
*
* public final Class getClass():返回此 Object 的运行时类
* Class类的方法:
* public String getName():以 String 的形式返回此 Class 对象所表示的实体
*/
public class StudentTest {
public static void main(String[] args) {
Student s1 = new Student();
System.out.println(s1.hashCode()); // 11299397
Student s2 = new Student();
System.out.println(s2.hashCode());// 24446859
Student s3 = s1;
System.out.println(s3.hashCode()); // 11299397
System.out.println("-----------");
 
Student s = new Student();
Class c = s.getClass();
String str = c.getName();
System.out.println(str); // cn.itcast_01.Student
 
//链式编程
String str2 = s.getClass().getName();
System.out.println(str2);
}
}
 
====================================================================
package cn.itcast_02;
 
/*
* public String toString():返回该对象的字符串表示。
*
* Integer类下的一个静态方法:
* public static String toHexString(int i):把一个整数转成一个十六进制表示的字符串
*
* 这个信息的组成我们讲解完毕了,但是这个信息是没有任何意义的。所以,建议所有子类都重写该方法。
* 怎么重写呢?
* 把该类的所有成员变量值组成返回即可。
* 重写的最终版方案就是自动生成toString()方法。
*
* 注意:
* 直接输出一个对象的名称,其实就是调用该对象的toString()方法。
*/
public class StudentDemo {
public static void main(String[] args) {
Student s = new Student();
System.out.println(s.hashCode());
System.out.println(s.getClass().getName());
System.out.println("--------------------");
System.out.println(s.toString());// cn.itcast_02.Student@42552c
System.out.println("--------------------");
// toString()方法的值等价于它
// getClass().getName() + '@' + Integer.toHexString(hashCode())
// this.getClass().getName()+'@'+Integer.toHexString(this.hashCode())
 
// cn.itcast_02.Student@42552c
// cn.itcast_02.Student@42552c
 
System.out.println(s.getClass().getName() + '@'
+ Integer.toHexString(s.hashCode()));
 
System.out.println(s.toString());
 
// 直接输出对象的名称
System.out.println(s); // cn.itcast_02.Student@42552c
}
}
============================================================
package cn.itcast_03;
 
/*
* public boolean equals(Object obj):指示其他某个对象是否与此对象“相等”。
* 这个方法,默认情况下比较的是地址值。比较地址值一般来说意义不大,所以我们要重写该方法。
* 怎么重写呢?
* 一般都是用来比较对象的成员变量值是否相同。
* 重写的代码优化:提高效率,提高程序的健壮性。
* 最终版:
* 其实还是自动生成。
*
* 看源码:
* public boolean equals(Object obj) {
* //this - s1
* //obj - s2
* return (this == obj);
* }
*
* ==:
* 基本类型:比较的就是值是否相同
* 引用类型:比较的就是地址值是否相同
* equals:
* 引用类型:默认情况下,比较的是地址值。
* 不过,我们可以根据情况自己重写该方法。一般重写都是自动生成,比较对象的成员变量值是否相同
*/
public class StudentDemo {
public static void main(String[] args) {
Student s1 = new Student("林青霞", 27);
Student s2 = new Student("林青霞", 27);
System.out.println(s1 == s2); // false
Student s3 = s1;
System.out.println(s1 == s3);// true
System.out.println("---------------");
 
System.out.println(s1.equals(s2)); // obj = s2; //false
System.out.println(s1.equals(s1)); // true
System.out.println(s1.equals(s3)); // true
Student s4 = new Student("风清扬",30);
System.out.println(s1.equals(s4)); //false
 
Demo d = new Demo();
System.out.println(s1.equals(d)); //ClassCastException
 
}
}
 
class Demo {}
 
 
 
 
package cn.itcast_03;
 
public class Student {
private String name;
private int age;
 
public Student() {
super();
}
 
public Student(String name, int age) {
super();
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;
}
 
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Student other = (Student) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
 
// @Override
// public boolean equals(Object obj) {
// // return true;
// //这里要改进,根据这里比较的成员变量来决定返回true还是false
// //这里其实要比价的就是name和age
// //但是,name是String类型的,而String是引用类型的,所以,在这里不能直接用==比较,应该用equals()比较
// //String的equals()方法是重写自Object类的,比较的是字符串的内容是否相同
// //this -- s1
// //obj -- s2
// //我们要使用的是学生类的特有成员变量,所以要向下转型
// Student s = (Student)obj; //s -- obj -- s2;
// if(this.name.equals(s.name) && this.age == s.age) {
// return true;
// }else {
// return false;
// }
// }
 
// @Override
// public boolean equals(Object obj) {
// //为了提高效率
// if(this == obj){
// return true;
// }
//
// //为了提供程序的健壮性
// //我先判断一下,obj是不是学生的一个对象,如果是,再做向下转型,如果不是,直接返回false。
// //这个时候,我们要判断的是对象是否是某个类的对象?
// //记住一个格式:对象名 instanceof 类名
// //表示:判断该对象名是否是该类名一个对象
// if(!(obj instanceof Student)){
// return false;
// }
// //如果是就继续
//
// Student s = (Student)obj;
// //System.out.println("同一个对象,还需要向下转型并比较吗?");
// return this.name.equals(s.name) && this.age == s.age;
// }
 
 
}
 
===========================================================================
package cn.itcast_04;
 
*
* Cloneable:此类实现了 Cloneable 接口,以指示 Object.clone() 方法可以合法地对该类实例进行按字段复制。
* 这个接口是标记接口,告诉我们实现该接口的类就可以实现对象的复制了。
*/
public class StudentDemo {
public static void main(String[] args) throws CloneNotSupportedException {
//创建学生对象
Student s = new Student();
s.setName("林青霞");
s.setAge(27);
 
//克隆学生对象
Object obj = s.clone();
Student s2 = (Student)obj;
System.out.println("---------");
 
System.out.println(s.getName()+"---"+s.getAge());
System.out.println(s2.getName()+"---"+s2.getAge());
 
//以前的做法
Student s3 = s;
System.out.println(s3.getName()+"---"+s3.getAge());
System.out.println("---------");
 
//其实是有区别的
s3.setName("刘意");
s3.setAge(30);
System.out.println(s.getName()+"---"+s.getAge());
System.out.println(s2.getName()+"---"+s2.getAge());
System.out.println(s3.getName()+"---"+s3.getAge());
 
}
}
 
 
package cn.itcast_04;
 
public class Student implements Cloneable {
private String name;
private int age;
 
public Student() {
super();
}
 
public Student(String name, int age) {
super();
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;
}
 
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
 
===========================================================================
1:Eclipse的安装
 
2:用Eclipse写一个HelloWorld案例,最终在控制台输出你的名字
 
A:创建项目
B:在src目录下创建包。cn.itcast
C:在cn.itcast包下创建类。HelloWorld
D:在HelloWorld下有一个方法。public static void main(String[] args) {}
E:在main方法中有一个输出语句。System.out.println("你的名字");
 
3:Eclipse空间的基本配置
A:程序的编译和运行的环境配置(一般不改)
window -- Preferences -- Java
编译环境:Compiler 默认选中的就是最高版本。
运行环境:Installed JREs 默认会找你安装的那个JDK。建议配置了Java的环境变量。
问题:
低编译,高运行。可以。
高编译,低运行。不可以。
建议,编译和运行的版本一致。
 
B:如何去掉默认注释?
window -- Preferences -- Java -- Code Style -- Code Templates
选择你不想要的内容,通过右边Edit编辑。
注意:请只删除注释部分,不是注释部分的不要删除。
 
C:行号的显示和隐藏
显示:在代码区域的最左边的空白区域,右键 -- Show Line Numbers即可。
隐藏:把上面的动作再做一次。
 
D:字体大小及颜色
a:Java代码区域的字体大小和颜色:
window -- Preferences -- General -- Appearance -- Colors And Fonts -- Java修改 -- Java Edit Text Font
b:控制台
window -- Preferences -- General -- Appearance -- Colors And Fonts -- Debug -- Console font
c:其他文件
window -- Preferences -- General -- Appearance -- Colors And Fonts -- Basic -- Text Font
 
E:窗体给弄乱了,怎么办?
window -- Reset Perspective
 
F:控制台找不到了,怎么办?
Window--Show View—Console
 
4:常用快捷键
A:格式化 ctrl+shift+f
B:导入包 ctrl+shift+o
如果该类仅仅在一个包中有,就自己显示了
如果该类在多个包中有,会弹出一个框框供你选择
C:注释
单行:注释 ctrl+/,取消注释再来一次。
多行:ctrl+shift+/,ctrl+shift+
D:代码上下移动
选中代码alt+上/下箭头
E:查看源码
选中类名(F3或者Ctrl+鼠标点击)
 
5:如何提高开发效率
A:自动生成构造方法
a:无参构造方法 在代码区域右键--source--Generate Constructors from Superclass
b:带参构造方法 在代码区域右键--source--Generate Constructors using fields.. -- finish
B:自动生成getXxx()/setXxx()方法
在代码区域右键--source--Generate Getters and Setters...
 
提供了对应的快捷键操作。
alt+shift+s
按下带有下划线的那个字母即可。
 
C:如何继承抽象类和实现接口。
D:Override的作用
表示该方法是重写父类的。如果方法声明和父类不匹配,就会报错。
 
6:通过讲解的快捷键和提高开发效率的一些内容完成如下内容
自定义学生类:Student
成员变量;
姓名
年龄
构造方法:
无参
带参
成员方法:
getXxx()/setXxx()
在给出一个show()方法,显示类的所有成员信息。
 
然后,写一个测试类,对学生的代码进行测试。
StudentDemo
 
7:删除项目和导入项目
删除项目
选中项目 – 右键 – 删除
从项目区域中删除
从硬盘上删除
 
导入项目
在项目区域右键找到import
找到General,展开,并找到
Existing Projects into Workspace
点击next,然后选择你要导入的项目
注意:这里选择的是项目名称
 
8:要注意的几个小问题
如何查看项目所在路径
选中 -- 右键 -- Properties -- Resource -- Location
导入项目要注意的问题
项目区域中不可能出现同名的项目(新建或者导入)
自己随意建立的文件夹是不能作为项目导入的
修改项目问题
不要随意修改项目名称
如果真要修改,不要忘记了配置文件.project中的
<name>把这里改为你改后的名称</name>
 
9:大家接收文件的注意事项
A:专门建立一个文件夹用于接收项目,不要随意放置。
B:同一个项目再次接收的时候,先去存放目录把原始项目删除,然后重新存储,最后刷新项目即可。
C:每天对照我写的项目,自己也创建一个练习项目
举例:我的项目名称 day11_eclipse
你就创建一个项目名称 day11_eclipse_test
 
10:Eclipse中代码的高级(Debug)调试
作用:
调试程序
查看程序执行流程
 
如何查看程序执行流程
要想看程序流程,就必须设置断点。
 
什么是断点:
就是一个标记,从哪里开始。
 
如何设置断点:
你想看哪里的程序,你就在那个有效程序的左边双击即可。
 
在哪里设置断点:
哪里不会点哪里。
目前:我们就在每个方法的第一条有效语句上都加。
 
如何运行设置断点后的程序:
右键 -- Debug as -- Java Application
 
看哪些地方:
Debug:断点测试的地方
在这个地方,记住F6,或者点击也可以。一次看一行的执行过程。
Variables:查看程序的变量变化
ForDemo:被查看的源文件
Console:控制台
 
如何去断点:
a:再次双击即可
b:找到Debug视图,Variables界面,找到Breakpoints,并点击,然后看到所有的断点,最后点击那个双叉。
 
 
 
 
原文地址:https://www.cnblogs.com/yejibigdata/p/7834968.html