面向对象,继承,抽象类,接口
1.封装
字段得封装 get:可读属性 set:可写属性 其实get,set方法不用自己写,而是可以生成。
1.如图
勾选字段的get,set方法,再点击生成。
package com.xinyisu.study;
public class T01 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Teacher t = new Teacher();
t.setName("张三");
t.setAge(6);
t.setCourse("6666");
t.teach();
String x= t.getTname();
String y = t.getCourseName();
int m = t.getTage();
System.out.println(x);
System.out.println("---------");
System.out.println(y);
System.out.println(m);
}
}
class Teacher
{
//属性
private int tid;//可读,不可写
private String tname;//可写,不可读
private int age;//可读 可写
private String courseName;//可读 可写
//私有的字段“通过方法”改写成可写(或者可读)
//可写
public void setName(String tname) {
this.tname = tname;
}
public void setAge(int age) {
this.age = age;
}
public void setCourse(String courseName) {
this.courseName = courseName;
}
//可读
public String getTname() {
return this.tname;
}
public int getTage() {
return this.age;
}
public int getTid() {
return this.tid;
}
public String getCourseName() {
return this.courseName;
}
//方法--字段
public void teach() {
System.out.println(this.tname+"教师需要授课!"+this.age);
}
}
3.get,set方法详解
有的可读可写,有的不可读,不可写,这个时候就要你自己判断了
2.继承
提高复用性 , 减少代码量 , is的关系,比如猫是动物,那么猫和动物就有继承关系。
继承的关键字是extends
Java只支持单继承
继承父类的所有成员属性(私有的也继承),但是,构造函数没有被继承。
Animal dog = new Dog(); // 向上转型
子类继承父类的成员,我们还要去改造继承过来的成员(主要指成员方法)
改造父类继承过来的成员方法 ,用方法的重写。
动态多态(运行时多态):在继承关系里面,相同的操作,作用在不同的实例上,
产生了不同的结果,要想多态必先变态(改变形态---向上转型一下)。
静态多态(编译时多态):方法的重载
父类中有一些方法禁止子类对其进行改造(不允许重写)。这个时候,我们用final关键字对该方法进行修饰。
有一些类不能有子类,我们可以用final关键字对该类进行修饰,该类为最终类。
package com.xinyisu.study;
public class T02 {
public static void main(String[] args) {
Cat cat = new Cat();
cat.speak();
// 多态,最重要是看new的对象是否是新的
Animal animal = new Dog();
animal.speak();
Animal animal1 = new Cat();
animal1.speak();
}
}
class Animal {
public String type;
public void speak() {
System.out.println("dont know speak");
}
final public void breath() {
System.out.println("must breath");
}
}
class Dog extends Animal {
@Override
public void speak() {
// super.speak();
System.out.println("狗在汪汪汪");
}
}
class Cat extends Animal {
@Override
public void speak() {
// TODO Auto-generated method stub
System.out.println("猫在喵喵喵");
}
}
2.这是面试常考的
继承:提高程序的可复用性,大大减少了代码量。
继承的关键字:extends
Java里面只支持单继承。
子类可以继承父类的成员( 成员字段,成员方法,构造函数不可以被继承 )
私有可以被继承,但是他变成不可见成员。
子类可以添加新功能
子类可以对父类的方法进行改造————重写
父类可以禁止子类改造父类的某些方法————用final关键字实现(final修饰的方法不能被重写)
限定这个类不能有子类,我可以在class的前面加上final关键字(final修饰的类就是最终类,不能被继承)
产生一个类对象,先调用父类的构造函数,再调用子类的构造函数。——————————栈实现的。
super关键字:父类的对象的引用
(1) super.成员 调用父类的成员
(2) super( 参数列表 ) 调用父类的构造函数
向上转型:Vehicle1 v = new Car(); Vehicle1和Car之间是父子类关系
static关键字:
用static关键字修饰的成员,我们叫做静态成员。可以修饰成员变量,也可以修饰成员方法。
不用static关键字修饰叫做 实例成员。
静态的成员是所有对象共享的(类共享的),实例的成员是属于某一个对象。
static的如何使用呀?什么时候用他?
工具类的设计,会经常的把里面的成员设置成静态的。工具类里面经常构造函数私有化。
final关键字:
(1) 修饰类的时候,该类不能为继承(最终类)。
(2) 修饰方法的时候,该方法不能被重写(最终方法)
(3) 修饰成员变量的时候,一旦该成员变量被初始化后,就不能被修改。
A. 构造函数
B. 实例块
C. 静态块
D. 声明这个变量的时候可以直接赋值
(4) 修饰局部变量的时候,一旦该局部变量被初始化后,就不能被修改。
(5) 修饰参数的时候,参数不可改变。
访问修饰符:
public:公共的,任何地方都可以访问,访问不受限制。
private:本类中访问。
package(缺省的,默认的):同包可以访问
protected:同包可以访问 或者 父子类
3.抽象类和接口
抽象类和接口都不能实例化
如果产生抽象类的对象,我们需要实例化该抽象类的非抽象子类
产生接口类型的对象,我们需要实例化接口的实现类
抽象类:事物的分类,词性是名词。
因为某些行为无法具体化。
单继承
苹果 ---> 水果
抽象方法:需要用abstract关键字修饰方法,并且不能有方法的实现。
在一个抽象类既可以有抽象方法,也可以非抽象方法。
抽象方法必须在抽象类里面,抽象类里面不一定有抽象方法。
抽象类不能被实例化。需要通过他的非抽象后代类来产生这个类型的对象。
接口:事物能力的体现,词性是动词或者形容词居多。
更高级的抽象,抽象到里面不能任何的实现。
多实现
接口的关键字是interface
接口的实现用implements关键字。
接口不能被实例化,我们通过接口的实现类来产生这个接口类型的对象。
飞(接口),听(接口)
鸟可以有飞的能力,也可以听的能力。
用到向上转型,就可能面临这丢失子类/实现类的特性。
1.抽象类
//抽象类
package com.xinyisu.study;
public class T01 {
public static void main(String[] args) {
// new不可抽象类,得new一个具体的
//多态
Animal animal = new Dog();
animal.speak();
animal.breath();
Animal animal1 = new Cat();
animal1.speak();
}
}
//抽象方法必须在抽象类里面
abstract class Animal{
//说话,抽象方法不可被实现(不可具体化),实现用{}说明
abstract public void speak();
//抽象类既可以有抽象方法(可无),也可以有非抽象方法
public void breath() {
System.out.println("breath air!!!");
}
}
//抽象类只能被单继承
//用一个非抽象类继承抽象类,然后实例化
class Dog extends Animal{
@Override
public void speak() {
//此时实现了
System.out.println("小狗汪汪汪");
}
}
//用快捷键
class Cat extends Animal{
@Override
public void speak() {
System.out.println("小猫都是喵喵喵");
}
}
2.接口的学习
//接口的学习
//接口不可实例化,通过接口的实例化来产生接口类型的对象
package com.xinyisu.study;
public class T02 {
public static void main(String[] args) {
//向上转型会丢失子类
IFly fly = new Bird();
fly.fly();
fly = new Person();
fly.fly();
//强制类型转换
IFly fly1 = new Bird();
fly1.fly();
Bird bird = (Bird)fly1;
bird.listen();
System.out.println(".....");
Bird bird2 = new Bird();
bird2.fly();
bird2.listen();
}
}
//I +名字
//写两个接口,高耦合,一个接口一个实现功能
interface IFly {
// 不加{},因为没有实现
public void fly();
}
interface IListen{
//方法,不能实现
public void listen();
}
//接口的实现用implements
//接口是更高级的抽象,里面不能有具体的方法
class Bird implements IFly,IListen {
@Override
public void fly() {
System.out.println("鸟有翅膀");
}
@Override
public void listen() {
System.out.println("鸟用耳朵听");
}
}
class Person implements IFly,IListen {
@Override
public void fly() {
System.out.println("person have dream!!!");
}
@Override
public void listen() {
System.out.println("人用耳朵听");
}
}
package com.xinyisu.study;
public class T03 {
public static void main(String[] args) {
// TODO Auto-generated method stub
PhonePrinter phone = new PhonePrinter();
phone.install();
phone.work();
PcPrinter pc = new PcPrinter();
pc.install();
pc.work();
System.out.println("......");
//new 只能开辟了空间,
IUsb[] usbs = new IUsb[3];
usbs[0] = new PcPrinter();
usbs[1] = new PcPrinter();
usbs[2] = new PcPrinter();
for (IUsb iUsb : usbs) {
iUsb.work();
}
}
}
interface IUsb{
public void install();
public void work();
}
class PhonePrinter implements IUsb{
@Override
public void install() {
System.out.println("安装手机驱动程序");
}
@Override
public void work() {
System.out.println("从电脑拷贝数据到手机上");
}
}
class PcPrinter implements IUsb{
@Override
public void install() {
System.out.println("安装打印机驱动程序");
}
@Override
public void work() {
System.out.println("打印一份文件");
}
}
4.方法的参数
可变参数
基本数据类型作为参数
引用类型作为参数---》数组,类类型,接口类型
当基本数据类型作为参数的时候,形参改变,实参不改变。(值数据的Copy)
当引用类型作为参数的时候,形参改变,实参也改变。
特殊的数据类型(引用类型):String和包装类型 虽然是引用类型,但是他们是引用类型的按值传递。
Java为基本数据类型提供对应的包装类型,例如: int —> Integer short —> Short byte
—> Byte long —> Long char —> Character boolean —> Boolean 这些类型都是形参改变,实参不发生改变。
1.参数的用法
package com.xinyisu.study;
//参数的用法
public class T04 {
public static void main(String[] args) {
int i =12;//局部变量
changeNumber(i);//实参的值为12
System.out.println("实参i的值"+i);
System.err.println("....");
Number num = new Number();
num.setI(12);
System.out.println("实参number.i的值"+(num.getI()));
}
//改变数字的值
public static void changeNumber(int i) {
i = 10;
System.out.println("形参i的值"+i);
}
//运用类型作为参数
public static void changeNumber(Number num) {
//.i点不出来,只能set,get
num.setI(10);
System.out.println("形参Number.i的值"+(num.getI()));
}
}
class Number{
private int i;//字段可读,可写
public int getI() {
return i;
}
public void setI(int i) {
this.i = i;
}
}
5.装箱,拆箱
基本数据类型到引用类型的隐式转换,叫做装箱。
int i = 0 ;
Integer j = i;
从引用类型到基本数据类型的转换,叫做拆箱。
package com.xinyisu.study;
//参数,什么东西都可做参数
//特殊的数据类型-->引用类型,应用类型的按值传递(string)
//java为基本数据类型提供了对于的包装类型(引用)
//short-->Short;long -->Long; character;byte;Integer
public class T05 {
public static void main(String[] args) {
//装箱
int i = 0;
//包装里有很多方法
Integer j = i;
//拆箱
//与装箱与之对应
String name = "张三";
changeString(name);
System.out.println("实参名字:"+name);
}
public static void changeString(String name) {
name = "李四";
System.out.println("形参名字:"+name);
}
}
6.object
Object:对象类型,所有类型的超类。 toString方法:继承过来的toString如果不重写的话,返回的是 全类名 +根地址相关的一个值。 我们经常会重写该方法,让他变得有意义。
equals:用来判断两个对象是否是相等的。
我们可以重写equals规则,来实现相等业务需求。
重写equals的同时一定要重写hashcode。
package com.xinyisu.study;
public class T06 {
//重写equal一定要重写hashcode
public static void main(String[] args) {
// TODO Auto-generated method stub
Teacher t = new Teacher(1001);
System.out.println(t.toString());
System.out.println("................");
//两个new,则两个地址
Teacher t1 = new Teacher(1002);
t1.setTname("张三");
Teacher t2 = new Teacher(1002);
t2.setTname("张三");
//equal判断两个对象是否相等
//用地址判断,地址相等则返回true
boolean bln = t1.equals(t2);
System.out.println(bln);
}
}
class Teacher {
// 属性(字段) 编号,姓名,年龄 ,课程 |
private int tid; // 设置成 可读 不可写 只写get方法
private String tname; // 可以写入,但是不可以读
private int age; // 可读 可写
private String courseName; // 可读 可写
public Teacher()
{
}
public Teacher( int tid )
{
this.tid = tid;
}
public String getTname() {
return tname;
}
public void setTname(String tname) {
this.tname = tname;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getCourseName() {
return courseName;
}
public void setCourseName(String courseName) {
this.courseName = courseName;
}
public int getTid() {
return tid;
}
// 行为 (方法) 授课
public void teach() {
System.out.println(this.tname + "教师需要授课!");
}
@Override
public String toString() {
return "Teacher [tid=" + tid + ", tname=" + tname + ", age=" + age + ", courseName=" + courseName + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + tid;
result = prime * result + ((tname == null) ? 0 : tname.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Teacher other = (Teacher) obj;
if (tid != other.tid)
return false;
if (tname == null) {
if (other.tname != null)
return false;
} else if (!tname.equals(other.tname))
return false;
return true;
}
// @Override
// public boolean equals(Object obj) {
// // TODO Auto-generated method stub
// Teacher t2 = (Teacher)obj;
// return this.tid == t2.tid;
// }
}