/*
学生事物:
属性:
姓名,年龄,性别...
行为:
学习,吃饭,睡觉...
把事物转换成Java中的类:
学生类:
成员变量:定义在类中,方法外的变量。
姓名,年龄,性别
成员方法:就是函数,先把static去掉。
学习,吃饭,睡觉
我们就用代码体现一下学生这个类。
*/
//创建 学生类:
class Student
{
//姓名
String name;
//年龄
int age;
//性别
char sex;
//学习的方法
public void study()
{
System.out.println("学生爱学习");
}
//吃饭的方法
public void eat()
{
System.out.println("学生吃饭");
}
//睡觉的方法
public void sleep()
{
System.out.println("学习睡觉");
}
}
//创建 学生测试类:
class StudentTest
{
public static void main(String[] args)
{
//你要想使用学生的内容,就首先必须明确你用哪个学生使用的。
//如何明确一个类的具体对象呢?通过new造出来。
//格式:类名 变量名 = new 类名(); 这就表示创建了一个数据类型为类名的变量。
//这个变量其实是一个对象。
//我要创建一个学生
Student s = new Student();
//那么,如何使用这个类中的成员变量和方法呢?
//必须通过对象调用。
//格式:
//成员变量:对象名.成员变量
//成员方法:对象名.成员方法
//获取成员变量的值
System.out.println(s.name+"***"+s.age+"***"+s.sex);//null,0,
System.out.println("-------------------");
//给成员变量赋值
s.name = "林青霞";
s.age = 26;
s.sex = '女';
//再次使用
System.out.println(s.name+"***"+s.age+"***"+s.sex);
System.out.println("-------------------");
//使用成员方法
s.study();
s.eat();
s.sleep();
System.out.println("-------------------");
}
}
/*
匿名对象:
是没有名字的对象。
应用场景:
A:当对对象方法仅进行一次调用的时
B:匿名对象可以作为实际参数进行传递
*/
class Student
{
public void show()
{
System.out.println("student -- show");
}
}
class Test
{
//引用类型作为形式参数
public void print(Student s)
{
s.show();
}
public void print(int a)
{
System.out.println(a);
}
}
class NiMingTest
{
public static void main(String[] args)
{
//如何使用show()方法呢?
Student s = new Student();
s.show();
s.show();
s.show();
//匿名对象的使用
new Student().show();
new Student().show();
new Student().show();
Test t = new Test();
//Student s2 = new Student();
//t.print(s2);
t.print(new Student());
}
}
封装
弊端:外界不能直接访问,变麻烦了。
(5)封装原则:将不需要对外提供的内容都隐藏起来,把属性都隐藏,提供公共方法对其访问。
(6)封装单例模式的运用:
a、Student类
package testdemo;
public 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;
}
}
b、饿汉式
package cn.itcast_sigleton;
public class Student {
// 把构造方法私有,是为了不让外界随意创建
private Student() {
}
// 类本身要创建一个对象。
// 由于静态只能访问静态,所以这里加静态
//为了不让外界通过类名直接访问s成员变量,就加私有
private static Student s = new Student();
// 提供公共的方式让别人使用
// 为了让外界能够直接通过类名访问该方法,需要对该方法加静态
public static Student getStudent() {
// return new Student(); //这是有问题的
return s;
}
public void show() {
System.out.println("hello");
}
// ...
}<strong>
</strong>
c、懒汉式
package cn.itcast_sigleton;
public class Teacher {
//私有无参 构造方法
private Teacher() {
}
//私有 Teacher类型的 引用变量 t
private static Teacher t = null;
public synchronized static Teacher getTeacher() {
// t1,t2,t3三个线程过来了
// 如果t是null的时候,才创建对象
if (t == null) {
//t1进来了,CPU的执行权就被t2抢到了,同理t3
t = new Teacher();
}
return t;
}
public void show() {
System.out.println("world");
}
}
(7)构造方法概述和使用
①、构造方法格式及特点:a、方法名必须和类名一致
b、没有返回值类型
c、没有具体的返回值
②、构造方法的作用:给对象进行初始化
③、注意事项:a、如果没有手动创建构造方法,系统会默认给出一个无参构造方法
b、假如创建了带参的构造方法,系统将不会提供无参的构造方法
c、构造方法可以重载
④、成员变量赋值:a、通过set()方法,推荐使用
b、通过构造方法
(8)this关键字的概述和应用
a、this的概述:this代表其所在方法所属对象的引用。换言之:this代表本类对象的引用
b、this的应用场景:用于解决局部变量隐藏成员变量值的 问题
c、代码体现:
/*
this关键字:this代表其所在方法所属对象的引用。
哪个对象调用方法,在方法内部就有一个隐含的this代表这个对象。
谁调用,this就代表谁。
*/
class Worker
{
//姓名
private String name;
//年龄
private int age;
//无参构造方法
public Worker(){}
public Worker(String name,int age)
{
this.name = name;
this.age = age;
}
public void setName(String name) //name="林青霞";
{
//name = name;
//假如我能够限定第一个name是成员变量的name
//我就能够把值赋值给成员变量的name
this.name = name;
//w.name = name;
}
public String getName()
{
return this.name;
//return name; //省略this
}
public void setAge(int age)
{
this.age = age;
}
public int getAge()
{
return age;
}
}
class WorkerTest
{
public static void main(String[] args)
{
//创建对象
Worker w = new Worker();
//输出成员变量的值
System.out.println(w.getName()+"---"+w.getAge());
//给成员变量赋值
w.setName("林青霞");
w.setAge(26);
System.out.println(w.getName()+"---"+w.getAge());
}
}
(9)代码块儿的概述
1、概念:就是用{}括起来的代码
2、分类:a、局部代码块,概念:定义在方法中的代码块儿,局部代码块儿。
作用:让变量尽可能早的从内存中消失,提高效率。
b、构造代码块,概念:定义在方法外的代码块,叫构造代码块儿
作用:把所有构造方法中的共同内容定义在构造代码块中
c、总结:构造代码块先执行,然后再执行构造函数
(10)static关键字的特点
1.static 是一个关键字。可以修饰成员变量和成员方法。
2.静态的特点:a、随着类的加载而加载
b、优先于对象存在
c、被类的所有对象共享
d、可以通过类名调用
3.静态的注意事项: a、在静态方法中是没有this关键字的。
b、静态方法只能访问静态成员。
4.静态内容的调用:a、被对象调用
b、被类名调用
5.应用场所:如果某个内容是所有对象共享的,就用静态修饰
2.继承
(1)概念:把多个类中的相同的属性和行为进行抽取,封装到一个类中。
然后再建立新类的时候,不需要从头做起,继承刚才定义的那个类即可。
(2)格式和叫法:a、格式: class 类A extends 类B{ //表示类A继承了类B }
b、叫法:类A,子类,派生类
类B,父类,基类,超类。
(3)注意:子类可以直接访问父类中的非私有的属性和行为
(4)继承的特点:a、Java只支持单继承,不支持多继承。【原因:如果支持多继承,就会有调用不明确的问题】
b、Java支持多层(重)继承。
(5)继承的好处:a、提高了代码的复用性
b、让类与类之间产生了一个关系
(6)应用场景:a、如果两个类之间有:A is B 的一种,或者 B is A,那么他们之间就存在继承关系。
b、注意:不要为了获取部分功能,而去使用继承
(7)this 和 super的 和应用:
a、this:代表本类对象的引用。
b、super:和this的用法很想,代表父类的内存空间的标示(可以理解为:父类对象的引用)
c、this和super的使用:
成员变量:this.变量--当前类的变量 super.变量--父类的变量
构造方法:this(参数)--本类的其他构造方法 super(参数)--父类的构造方法
成员方法:this.方法名()--本类的方法 super.(方法名)--父类的方法
d、代码体现:
package testdemo;
class Fu
{
public int num = 10;
}
class Zi extends Fu
{
public int num = 30;
public int num2 = 20;
public void show()
{
int num = 40;
System.out.println(num);
System.out.println(this.num);
System.out.println(super.num);
System.out.println(num2);
}
}
public class ExtendsDemo4
{
public static void main(String[] args)
{
Zi z = new Zi();
z.show();
}
}
运行结果如下:
(8)方法的重写:
a、子类成员方法调用:先找子类,再找父类。
b、概念:子类中出现于父类一模一样的方法是,会出现覆盖操作,也成为重写或者复写
c、注意事项:a、父类中私有方法是不能被重写的
b、子类方法的访问权限一定要大于等于父类的访问权限
c、静态只能重写静态。(这个不能算,因为静态跟类相关)
(9)子父类中构造方法的用法:
a、子类的初始化过程中,首先会去执行父类的初始化动作。因为子类的构造方法中默认有一个
为什么?子类要使用父类的成员变量,这个初始化,必须在子类初始化之前完成。
所以,子类的初始化过程中,会先执行父类的初始化。
b、如果父类没有无参构造方法
#使用super调用父类的带参构造。推荐方式。
#使用this调用本身的其他构造。[但是其他的构造方法必须能初始化父类]
c、代码体现:
package testdemo;
class Fu
{
public Fu()
{
System.out.println("fu");
}
}
class Zi extends Fu
{
public Zi()
{
super();
System.out.println("zi");
}
}
public class ExtendsDemo4
{
public static void main(String[] args)
{
Zi z = new Zi();
}
}
运行结果:
(10)代码块的执行顺序:
a、静态代码块 --> 构造代码块 --> 构造方法
b、注意:静态代码块只执行一次(class字节码文件只加载一次的情况下)
(11)final关键字:
a、final:是一个关键字,可以用于修饰类,成员变量,成员方法。
b、特点:# 它修饰的类不能被继承。
# 它修饰的成员变量是一个常量。
# 它修饰的成员方法是不能被子类重写的。
d、代码体现:
package testdemo;
class Fu
{
public final int X = 10;
public final void show()
{
System.out.println("这是绝密资源");
}
}
class Zi extends Fu
{
/*父类中的show()方法被final修饰了 不能重写
* public void show()
{
System.out.println("这是一堆垃圾,给处理了");
}*/
public void method()
{
//X = 20; 父类中的X被final 修饰了,不可以访问
System.out.println(X);
}
}
public class FinalDemo
{
public static void main(String[] args)
{
Zi z = new Zi();
z.show();
z.method();
}
}
运行结果:
3.多态
(1)多态的概述与前提:
a、多态:对象在不同时刻表现出来的不同状态。
b、前提:①、要有继承或者实现关系。
②、要有方法的重写/实现。
③、要有父类引用或者父接口引用指向子类对象。
c、多态的三种体现形式:
①、类多态; ②、抽象类多态;③、接口多态;
(2)多态的弊端:父类(接口)引用不能使用子类特有功能。
为了解决这个弊端,我们需要向下转型。
Fu f = new Zi(); //向上转型
Zi z = (Zi)f; //向下转型
(3)多态的好处:可以提高代码的扩展性和可维护性。
(4)多态代码体现:
package testdemo;
/*
多态的好处:
为了提高代码的扩展性和可维护性。
*/
class Animal {
public void show() {
System.out.println("show");
}
public void eat() {
System.out.println("eat");
}
}
class Cat extends Animal {
public void show() {
System.out.println("show cat");
}
public void eat() {
System.out.println("eat 老鼠");
}
}
class Dog extends Animal {
public void show() {
System.out.println("show dog");
}
public void eat() {
System.out.println("eat 骨头");
}
}
class Pig extends Animal {
public void show() {
System.out.println("show pig");
}
public void eat() {
System.out.println("eat 饲料");
}
}
class AnimalTool {
private AnimalTool() {
}
public static void printAnimal(Animal a) {
a.show();
a.eat();
}
}
public class DuoTaiDemo5 {
public static void main(String[] args) {
AnimalTool.printAnimal(new Dog());
AnimalTool.printAnimal(new Dog());
AnimalTool.printAnimal(new Dog());
System.out.println("-----------------------");
AnimalTool.printAnimal(new Cat());
AnimalTool.printAnimal(new Cat());
AnimalTool.printAnimal(new Cat());
System.out.println("-----------------------");
AnimalTool.printAnimal(new Pig());
AnimalTool.printAnimal(new Pig());
AnimalTool.printAnimal(new Pig());
System.out.println("-----------------------");
}
}
运行结果: